Reputation: 3658
It's surprising for me to see that even when the value can be converted, an int to float conversion always give a warning. Why is this?
int i = 0;
float f = 0; // warning here
// I thought this was an implicit conversion,
// meaning it is convertible with no warnings.
f = i; // another warning here
The warning is:
warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
Upvotes: 15
Views: 30862
Reputation: 263177
// I thought this was implicit conversion means it is covertible with no warnings?
No, that's not what it means. It just means that you can assign a value of one type to an object of another type without an explicit conversion (i.e., a cast), and the value will be converted implicitly.
And in this case, a warning could be appropriate. If int
and float
are both 32 bits (which is typical but not universal), then all values of type int
are within the range of float
, but there are many values of type int
that cannot be represented exactly in type float
.
The language standard requires at least one diagnostic message for any translation unit (source file) that violates a syntax rule or constraint. But compilers are free to issue any additional diagnostic that they like.
Upvotes: 0
Reputation: 10122
Just for fun, try this and see what the output is (hint, you would expect the numbers to all be the same, wouldn't you?):
int i1(INT_MAX), i2;
float f(i1);
i2 = f;
std::cout << i1 << ' ' << f << ' ' << i2 << '\n';
Well, the answers I get are:
2147483647 2.14748e+009 -2147483648
So the compiler is quite right to point out that something might go wrong with the cast, but it isn't clever enough to know for sure, because it will only tend to happen at the extremities of the numerical range. It's always best to static_cast<> in my view, for clarity at least, and to show the compiler that it was what you intended.
By the way I'm not entirely sure why the above result happens. Perhaps someone else can explain!
Upvotes: 3
Reputation: 881093
It depends on how many bits you have in your int
type. A float that is IEEE754 single precision is a 32-bit value but some of those bits are assigned to the exponent, meaning not all are available for precision.
If your int
type has more precision than your float
, then you may suffer loss of precision at the high end.
In other words, it may not be able to distinguish between INT_MAX
and INT_MAX - 1
.
Solution in that case is to use a wider floating point type (double
) although, technically, you may find an implementation that has a 256-bit int
type in which case you'll have to find another way :-)
This answer has a brief overview of how the floating point formats work, including the fact that only 23 of the 32 bits are available for the precision of the mantissa.
Upvotes: 17
Reputation: 471209
I answered a similar question here:
Why does GCC warn against this implicit conversion?
The reason is that an int
needs to be rounded when it is casted into a float
because float
cannot contain all the precision of an int
in this case.
In your case, a float
only has about 24 bits of precision. While an int
has 32 bits of precision, therefore, some precision is loss by this cast, hence the warning.
Upvotes: 6