-4
for (float x = 0.00; x < 1.00; x += 0.01) {
    cout << x << endl;
}

I expect

0.00
0.01
0.02
...

And it works fine, until 0.83:

...
0.81
0.82
0.83
0.839999
0.849999
0.859999
0.869999
0.879999
0.889999
0.899999
0.909999
0.919999
0.929999
0.939999
0.949999
0.959999
0.969999
0.979999
0.989999
0.999999

What's up with that part? Why all the extra 9s?

Charles
  • 50,943
  • 13
  • 104
  • 142
Saturn
  • 17,888
  • 49
  • 145
  • 271

1 Answers1

11

Please read What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Floating point types can not represent every possible numeric value. They have some imprecision. The closest representable IEEE754 single-precision floating point value to 0.84 is 0.839999973773956298828125. This is a little less than 0.84. As you have seen, when printed, this is shown as as 0.839999. The binary representation of this number is:

00111111 01010111 00001010 00111101

In fact, even 0.01 is not exactly representable with float, so every time you add this value to x, your expectation becomes less and less precise. You can avoid this by using ints instead, like so:

for (int x = 0; x < 100; x += 1) {
    cout << (x / 100.0f) << endl;
}

However, many of the values it prints will still not be representable after performing the division. If you can't deal with imprecision at all, you must simply not work with floating point values. Store your values as ints and simply interpret them as representing the corresponding divided by 100 float value.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324