2

There are some cases of int to float casting, I found the original value changes.

For example:

int x = 49941310;
float y = (float) (x);
int z = (int) (y);

printf("%d, %f, %d",x,y,z);

Expecting: 49941310, 49941310.0000, 49941310...
Actual:    49941310, 49941312.0000, 49941312...

In case of 18595769 I get 18595768.

I also tried static_cast in c++, same things happened. I know 23 bits to store the mantissa and 9 to store the sign and exponent. My question is, If I want original value back what should I do?

  • Which book are you using? This is kind of a fundamental computer thing. – Lightness Races in Orbit Feb 21 '19 at 16:54
  • Hint: use `double` instead of `float` – Jabberwocky Feb 21 '19 at 16:54
  • Related answer : https://stackoverflow.com/a/23423240/7359094 – François Andrieux Feb 21 '19 at 16:54
  • 3
    Hint: don't hack around problems like this by just increasing the precision of your floating-point type, rather than understanding the ramifications of using a floating-point type – Lightness Races in Orbit Feb 21 '19 at 16:55
  • 1
    I'm not sure if I agree with the dupe but it is precision issue so I'll leave it. a `float` only has 23 bits of precision which `49941310` can't fit into. That means it needs to convert it to a decimal number that can by changing the value and using the 8 bits it has for the exponent. That process loses information. – NathanOliver Feb 21 '19 at 16:57
  • Much better dupe now. Thanks @jamesdlin – NathanOliver Feb 21 '19 at 17:01
  • 2
    If you want to preserve the original value, preserver the original value. Keep your integer as an integer. Don't rely on any floating point type to precisely store the value of an integer (it's okay for fairly small values, but in my experience, once you rely on that, it will come back to bite you). – Tim Randall Feb 21 '19 at 17:16
  • Remember: float (or even double) can only hold so many digits of precision. It doesn't care if you have a really big number or just 0.12345 (etc). At some point, it rounds off. If you can't handle rounding, you need to use a library that does infinite-precision floating point math. – Joseph Larson Feb 22 '19 at 06:36
  • "I found the original value changes." --> Think of it this way. `int` and `float` typically use 32-bits to encode. That is about 4,000,000,000 patterns. For the `int`, they are all integers. For `float`, there are many values like 0.5, 4.125, etc. that are not in the `int` set. Some of the `int` values are not in the `float` set, including `INT_MAX`. – chux - Reinstate Monica Feb 22 '19 at 07:26
  • @NathanOliver [Off-by-1](https://stackoverflow.com/questions/54812314/casting-int-to-float-changes-value#comment96401499_54812314). [binary32](https://en.wikipedia.org/wiki/Single-precision_floating-point_format) has 24 bits of binary precision, 23 explicitly encoded, 1 implied. Typical `float` can encode all `uint24_t` and `int25_t`. – chux - Reinstate Monica Feb 22 '19 at 07:29

0 Answers0