1
int i = 0;
double n = 1.24;
    for (; int(n) != n; i++) {
        n *= 10;
    }

Why does it enter an infinite loop? Shouldn't it stop after two loops?

fpiro07
  • 847
  • 1
  • 13
  • 18

3 Answers3

9

1.24 cannot be represented exactly as a double. If you examine the initial value of n, you'll see that it is 1.239999999999999991118215802998747...

As to why the loop never stops, once n exceeds the value of the largest double, it is automatically converted to +Infinity, which is a special floating-point value. Once you've reached that point, n stops changing and int(n) != n can never be satisfied.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 3
    @fpiro07 Because `0.5` *can* be represented exactly (`0.5 == 2^-1`) – Magnus Hoff Dec 17 '12 at 13:02
  • But the debugger actually says that `n` is `1.24`, not `1.239999999...` – fpiro07 Dec 17 '12 at 13:03
  • @fpiro07: That's because you're not asking the debugger to print the value to enough significant digits to see this. – NPE Dec 17 '12 at 13:05
  • Ok so can I fix it with something like `int(n)-n < EPSILON`? – fpiro07 Dec 17 '12 at 13:07
  • @fpiro07: That might work. Whether or not it's a sensible workaround depends on how this code came about, and what you're expecting from it. – NPE Dec 17 '12 at 13:09
  • @fpiro07: If you do do this, don't forget to take the absolute value (since `int(n)-n` can be negative as well as positive). – NPE Dec 17 '12 at 13:10
  • Ok... Do you maybe have a better solution to my problem? (Transforming `1.24` into `124`, or `3.4213` into `34213` and so on...) – fpiro07 Dec 17 '12 at 13:12
4

Because double is not exact representation of number and condition int(n) == n never reached. Read this http://en.wikipedia.org/wiki/Floating_point

kassak
  • 3,974
  • 1
  • 25
  • 36
1

I have tried it, and it stops for after two loops. I have used gcc. I changed int(n) to (int)n

The infinite loop happens due to some rounding error, try to check the difference between (int)n and n

In general, do not use equally to check equality with double. Use instead

if (fabs(a-b)<1e-10) //instead of a==b

Khalefa
  • 2,294
  • 3
  • 14
  • 12
  • I seem to be able to reproduce the problem by using a `long double`: http://ideone.com/UrSxGc – Magnus Hoff Dec 17 '12 at 13:09
  • Is `1e-10` equal to `numeric_limits::epsilon()`? Or is it better to place `epsilon`? – fpiro07 Dec 17 '12 at 13:10
  • you can use arbitrary small value (It is better to have defined using #define).it should be greater than numeric_limits::epsilon() because error propagates in calculations. Refer to numerical analysis for more details – Khalefa Dec 17 '12 at 13:14