Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Precision of multiplication by 1.0 and int to float conversion

Is it safe to assume that the condition (int)(i * 1.0f) == i is true for any integer i?

like image 836
Violet Giraffe Avatar asked Nov 15 '12 15:11

Violet Giraffe


People also ask

What happens if you multiply a float by an int?

The result of the multiplication of a float and an int is a float . Besides that, it will get promoted to double when passing to printf . You need a %a , %e , %f or %g format. The %d format is used to print int types.

Is 1.5 float or double?

And the reason the comparison succeeds with 1.5 is that 1.5 can be represented exactly as a float and as a double ; it has a bunch of zeros in its low bits, so when the promotion adds zeros the result is the same as the double representation.

Can I convert int to float?

To convert an integer data type to float you can wrap the integer with float64() or float32. Explanation: Firstly we declare a variable x of type int64 with a value of 5. Then we wrap x with float64(), which converts the integer 5 to float value of 5.00. The %.


2 Answers

No.

If i is sufficiently large that int(float(i)) != i (assuming float is IEEE-754 single precision, i = 0x1000001 suffices to exhibit this) then this is false, because multiplication by 1.0f forces a conversion to float, which changes the value even though the subsequent multiplication does not.

However, if i is a 32-bit integer and double is IEEE-754 double, then it is true that int(i*1.0) == i.


Just to be totally clear, multiplication by 1.0f is exact. It's the conversion from int to float that may not be.

like image 86
Stephen Canon Avatar answered Sep 22 '22 03:09

Stephen Canon


No, IEEE-754 floating point numbers have a greater dynamic range than integers at the cost of integer precision for the same bit width.

See for example the output of this little snippet:

int main() {         int x = 43046721;          float y = x;          printf("%d\n", x);         printf("%f\n", y); } 

43046721 cannot be represented correctly in the 24 bits of precision available in a 32-bit float number, so the output is something along these lines:

43046721 43046720.000000 

In fact, I would expect any odd number above 16,777,216 to have the same issue when converting to a 32-bit float number.

A few points of interest:

  • This has more to do with the implicit int-to-float conversion than with the multiplication itself.

  • This is not by any mean unique to C - for example Java is also subject to the exact same issue.

  • Most compilers have optimization options that may affect how such conversions are handled, by ignoring certain restrictions of the standard. In such a case, (int)((float)x * 1.0f) == x might always be true if the compiler optimizes out the conversion to float and back.

like image 45
thkala Avatar answered Sep 22 '22 03:09

thkala