2

Possible Duplicate:
Floating point arithmetic not producing exact results in Java

I was doing this simple division but I get a very strange output:

double a = 60/(1.2-1.1);

a => 600.0000000000008

When it should be 600.

thanks in advance

Community
  • 1
  • 1
alkz
  • 337
  • 2
  • 7
  • 17
  • Please try creating a second double variable for the denominator: double b = 1.2-1.1; double a = 60/b; Same result? – Cody S Dec 14 '11 at 20:40
  • Second time this question is asked today, just in the Java tag. Must be the most asked question with "how to parse a date". – JB Nizet Dec 14 '11 at 20:47
  • 1
    @AndrewThompson No this is not a duplicate of that at all. That question relates to the difference between integer division and real floating point division. This question relates to the fact that not all real numbers have 64-bit floating point representations. – Michael McGowan Dec 14 '11 at 20:52
  • 2
    @MartijnCourteaux That's not a dup either. If you are looking for a duplicate, a better example would be [this](http://stackoverflow.com/q/1661273/387852). – Michael McGowan Dec 14 '11 at 20:58
  • 1
    Hey guys please stop closing this as a duplicate of question about **integer division**. This question is a problem of floating point arithmetic, not integer division. – kennytm Dec 14 '11 at 21:34

6 Answers6

12

In IEEE-754 binary double, we need to consider 1.1 and 1.2 in the binary representation:

1.2 = 0b1.001100110011001100110011001100110011001100110011001100110011...
1.1 = 0b1.000110011001100110011001100110011001100110011001100110011001...

note that we need infinitely many bits to represent them exactly in binary. double only has 53 bits of significance, we have to chop off the numbers:

1.2 = 0b1.001100110011001100110011001100110011001100110011001100110011...
1.1 = 0b1.000110011001100110011001100110011001100110011001100110011001...
                                                              ^ round from here
==>
1.2 ~ 0b1.0011001100110011001100110011001100110011001100110011
      (= exactly 1.1999999999999999555910790149937383830547332763671875)
1.1 ~ 0b1.0001100110011001100110011001100110011001100110011010
      (= exactly 1.100000000000000088817841970012523233890533447265625)

Hence 1.2 - 1.1 is:

  1.2 ~ 0b1.0011001100110011001100110011001100110011001100110011
- 1.1 ~ 0b1.0001100110011001100110011001100110011001100110011010
————————————————————————————————————————————————————————————————
        0b0.00011001100110011001100110011001100110011001100110010000
        (= exactly 0.09999999999999986677323704498121514916419982910156250000)

We can actually compute 60 / 0.0999999999999998667732370449812151491641998291015625 exactly, which gives

600.0000000000007993605777301137740672368493927467455286920109359612256820927...
                ^ 16th significant figure

that matches OP's result of

600.0000000000008
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
5

Because the double primitive is a floating point data type which trades precision for the ability to hold a larger range of values.

If you need arbitrary precision you should be using BigDecimal instead.

Kaleb Brasee
  • 51,193
  • 8
  • 108
  • 113
4

You've discovered the wonders of floating point arithmetic. Since the internal representation of a number is in binary, certain decimal numbers can't be represented precisely. As a result, some arithmetic operations will give unexpected results in the least significant digits.

This is covered in exhausting detail in, for example, numerical methods courses, but the Wikipedia article isn't bad.

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
3

You probably should read "What Every Computer Scientist Should Know About Floating-Point Arithmetic".

In short, not all real values can be represented exactly with a double, so they should be avoided when exact answers are required.

Michael McGowan
  • 6,528
  • 8
  • 42
  • 70
2

You should use BigDecimal to get correct result.

ArtemStorozhuk
  • 8,715
  • 4
  • 35
  • 53
1

This is not precisely a "rounding issue." Certain numbers cannot be exactly represented in binary floating point. Just like 1/3 cannot be represented exactly in decimal, since nobody has an infinite supply of paper. (or bits).

user949300
  • 15,364
  • 7
  • 35
  • 66