ahmad_mamdouh's blog

By ahmad_mamdouh, 13 years ago, In English

In most of the courses studied in the college , I was always told to take care of the double precision errors and never to compare two double(float) numbers with the equal operator .
But the problem I faced now is a bit different , let's think of this JAVA snippet of code :


double x = 2.55 ;
double y = x * 100 ;
System.out.println(y) ;

You'll be astonished with the result , you'll see " 254.99999999999997 " .
The problem will propagate if you're going to use the integer portion of the result which will yield  " 254 " instead of " 255 " .

The problem arose due to the infinite double representation inside the computer which can't be accurate as it's not terminating . However , the solution is very easy .
If you added a very small value to the resulted double ( EPS = 1e-9 ) .
you'll find that y = 255.00000000099996 so you'll get the correct result up to the accuracy you adjusted ( i.e 10^-9 accuracy ) .

Some algorithms problems will always give you wrong answer if you don't take care of such gotchas like this one : Transmigration .

  • Vote: I like it
  • 0
  • Vote: I do not like it

| Write comment?
13 years ago, # |
  Vote: I like it 0 Vote: I do not like it
I fear there are very few people who would be really astonished with these facts. When you were told beware of comparing two real values (not necessarily "double") you should not only write it down to your copy-book, but also try to think why it is so.

You can find a lot of fun effects with floating-point values by the way.

For example (stolen from Java Language Specification):

double a = SECRET_VALUE_1;
double b = SECRET_VALUE_2;
System.out.println(a == b); // prints "true"
a = 1 / a;
b = 1 / b;
System.out.println(a == b); // prints "false"

Guess these "secret values"!
  • 13 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it
    The problem in my example arose from the infinite binary representation of the number which can't fit in the real data representation .

    About your funny fact :
    I think that SECRET_VALUE_1 and SECRET_VALUE_2 are 0.0 and -0.0 .
    When you compare them together you'll get true as they are represented using two's complement notation .
    But when getting their reciprocal , 0.0 will give Infinity and -0.0 will give negative Infinity which are not equal of course .

    Nice one :)
    • 13 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it
      Correctly! ;-)

      Other annoying thing (which you also maybe aware of):

      double x = SECRET_VALUE_3;
      System.out.println(x == x); // prints "false"