C++ type converting issue - c++

Consider following code:
#include <iostream>
using namespace std;
int aaa(int a) {
cout << a * 0.3 << endl;
return a * 0.3;
}
int main()
{
cout << aaa(35000);
}
It prints out:
10500
10499
Why output differs?
I have a workaround to use "return a * 3 / 10;" but I don't like it.
Edit:
Found that doing "return float(a * 0.3);" gives expected value;

The result of 0.3*35000 is a floating point number, just slightly less than 10500. When printed it is rounded to 10500, but when coerced into an int the fractional digits are discarded, resulting in 10499.

int * double expression yields double, that's what the first thing prints.
Then you convert to int chopping the remaining part (even if it's almost there, sitting at 10500-DBL_EPSILON), and pass that back. The second prints that value.
float-int conversions should be made with care, better not at all.

a * 0.3 has type double. The call inside aaa calls
ostream& operator<< (double val);
whereas the one outside calls
ostream& operator<< (int val);
You'd get a warning (if you turn them on - I suggest you do) that the implicit cast from double to int isn't recommended.

Related

Query about function overloading

When using function with same name, parameter list must differ(either in type of parameter or number of parameters used). I was just practicing with this concept. I wrote the following code.
#include <iostream>
int myFunction(int n)
{
return 2*n;
}
float myFunction(float n)
{
return 3*n;
}
int main()
{
int x=myFunction(3);
std::cout << x;
return 0;
}
I thought I will get error because compiler will get confused which myFunction to use because I directly pass the value 3 without storing it in a particular type of variable . But I got output 6. So I tried the following code.
#include <iostream>
int myFunction(int n)
{
return 2*n;
}
float myFunction(float n)
{
return 3*n;
}
int main()
{
float x=myFunction(3.3);
std::cout << x;
return 0;
}
As previous one worked fine, I thought this will work fine too, as 3.3 is not integer so it's clear which one to call, but this time I got compiler error saying it's ambiguous.
So my doubt is why first code worked but not second one.
The process of selecting the overload during a call is called overload resolution. Given the types of the arguments, the compiler selects the best viable function from the list of candidates - the one that can be invoked with the least amount of promotions and implicit conversions.
In the first case the first one myFunction(int) requires 0 conversions for an int argument (3), and the second one requires one conversion (int -> float), so the first one is selected as the best candidate.
In the second case a double argument (3.3) requires a conversion to either int or float, so there is no clear winner and thus the call is ambiguous.
The fix could be to use a float argument (3.3f) or change myFunction(float) to myFunction(double).
Literals have types too. As integer literal 3 is of type int, then the 1st overload is selected.
As floating point literal 3.3 is of type double (but not float; with the suffix f like 3.3f the type is determined as float), the calling is ambiguous because it could convert to both int and float implicitly.
try this:
int x=myFunction(int(3));
float x=myFunction(float(3.3));

error when trying to run an overloaded function with float parameters.

I am trying to create a simple (absolute) function in c++, I have created two functions with the same name one that takes an integer and returns an integer and one that takes a float and returns a float but every time I try to run the code I receive this error:
"error: call of overloaded 'absolute(double)' is ambiguous"
I tried changing the input parameters of the second function so that it takes a double and returns a float and the code ran perfectly, I'd like to know why the code won't run when the parameters and return type are both set to float, thank you.
#include <iostream>
#include <fstream>
using namespace std;
int absolute(int x){
if (x<0){
x=-x;
}
return x;
}
float absolute (float x)
{
if (x<0){
x=-x;
}
return x;
}
int main( )
{
cout << absolute(3.5);
}
The type of the literal 3.5 is double, not float.
Choosing either of the overloads would require a conversion. Hence the ambiguity.
You can use 3.5f to make it a float literal.
cout << absolute(3.5f);
A better solution, IMO, would be to use a function template.
template <typename T>
T absolute(T x)
{
return (x < 0 ? -x : x);
}
Read that error message again. Notice how it says double as the argument type it want to use.
That's because floating point constants like 3.5 are of type double. And the compiler don't know if it should convert the double value to an int or a float, thereby giving you the error.
If you want to call the float overload, use 3.5f to make it a float value. Or change your overload to use type double instead of float.
you write that 3.5 is a float this value is not a float it is a double.

c++ changing implicit conversion from double to int

I have code which has a lot of conversions from double to int . The code can be seen as
double n = 5.78;
int d = n; // double implicitly converted to a int
The implicit conversion from double to int is that of a truncation which means 5.78 will be saved as 5 . However it has been decided to change this behavior with custom rounding off .
One approach to such problem would be to have your own DOUBLE and INT data types and use conversion operators but alas my code is big and I am not allowed to do much changes . Another approach i thought of was to add 0.5 in each of the numbers but alas the code is big and i was changing too much .
What can be a simple approach to change double to int conversion behaviour which impact the whole code.
You can use uniform initialization syntax to forbid narrowing conversions:
double a;
int b{a}; // error
If you don't want that, you can use std::round function (or its sisters std::ceil/std::floor/std::trunc):
int b = std::round(a);
If you want minimal diff changes, here's what you can do. Please note, though, that this is a bad solution (if it can be named that), and much more likely leaving you crashing and burning due to undefined behavior than actually solving real problems.
Define your custom Int type that handles conversions the way you want it to:
class MyInt
{
//...
};
then evilly replace each occurence of int with MyInt with the help of preprocessor black magic:
#define int MyInt
Problems:
if you accidentally change definitions in the standard library - you're in the UB-land
if you change the return type of main - you're in the UB-land
if you change the definition of a function but not it's forward declarations - you're in the UB/linker error land. Or in the silently-calling-different-overload-land.
probably more.
Do something like this:
#include <iostream>
using namespace std;
int myConvert (double rhs)
{
int answer = (int)rhs; //do something fancier here to meet your needs
return answer;
}
int main()
{
double n = 5.78;
int d = myConvert(n);
cout << "d = " << d << endl;
return 0;
}
You can make myConvert as fancy as you want. Otherwise, you could define your own class for int (e.g. myInt class) and overload the = operator to do the right conversion.

Am getting error as "Expression must have (pointer-to-)function type" in c++

Hi i have the below code
# include <iostream>
# include <limits>
# include <cmath>
using namespace std;
class fahrenheit
{
float f,c,x;
public:
void getdata();
void display();
}
void fahrenheit::getdata()
{
cout << "Enter the value of f : ";
cin >> f;
x=f-32;
c=5/9(x); //Here i am getting error as Expression must have (pointer-to-)function type //
}
void fahrenheit::display()
{
cout << "c=" << c;
std::cin.ignore();
std::cin.get();
}
int main()
{
fahrenheit f;
f.getdata();
f.display();
}
i have given the datatype as float for the input variables , but i am not sure what should be done to rectify the error .
5/9(x) doesn't remotely look like C++. You likely meant c = 5.0 / 9.0 * x;
first of all, you forgot about a semicolon right after the class definition.
Second, I presume you wanted to multiply x by 9. Write
c=5/9*(x)
otherwise the compiler tries to find a function called 9(int x) (which is an incorrect name for a function anyway) and realizes that 9 is in no sense any function pointer but just an int.. that's what the error means.
By the way.. if you write 5/9 compiler understands it as int values being divided.
It will divide int(5) by 9 using an int / operator, which after dividing will return
floor(5/9) = 0 . If you want to have a float or double division you have to inform the compiler that your values are floats(doubles).
For doubles: 5.0/9.0*x
For floats: 5.0f/9.0f * x
You should use the multiplication operator *.
c=5/9*(x);

How to determine type of the value of an expression?

1) When statements such as
cout << 3.0 + 3 ;
are made, how does one know whether the value passed to cout is an int or a float?
It's neither. It's a double. 3.0 has type double, and 3 is promoted to double for the addition; the result of adding a double to a double is a double. That's independent of what's being done with the result.
There are a bunch of overloaded shift-left operators for ostreams, and there's one for an argument of type double on the right-hand side, so that's the one that's called:
template <class Elem, class Traits>
basic_ostream<Elem, Traits>& basic_ostream<Elem, Traits>::operator<<(double d);
For what it's worth, that's a member function, not a free function.
It does this by taking advantage of overloading
ostream& operator<<(ostream& output, int i) {
// It's an int
}
ostream& operator<<(ostream& output, float f) {
// it's a float
}
The C++ compiler will pick the appropriate overload of the << operator based on the input types. If you pass a float it will pick the overload which has a float and the same for int
Result of 3.0 + 3 operation is double thus cout will apply the << operator for double type.
You may use Step into feature of debugger to determine this. In which cout method it will enter it is your answer