4

I have 2 numbers stored as Double, 1.4300 and 1.4350. When I subtract 1.4350 - 1.4300, it gives me the result: 0.0050000000000001155. Why does it add 1155 to the end and how can I solve this so that it returns 0.005 or 0.0050? I'm not sure rounding will work as I'm working with 2 and 4 decimal numbers.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Roger
  • 4,249
  • 10
  • 42
  • 60

3 Answers3

14

Oh, I love these... these are caused by inaccuracy in the double representation and floating-point arithmetic is full of these. It is often caused by recurring numbers in binary (i.e. base-2 floating-point representation). For example, in decimal 1/3 = 0.3333' In binary 1/10 is a recurring number, which means it cannot be perfectly represented. Try this: 1 - 0.1 - 0.1 - 0.1 - 0.1. You wont get 0.6 :-)

To solve this, use BigDecimal (preferred) or manipulating the double by first multiplying it something like 10000, then rounding it and then dividing it again (less clean).

Good question... it has caused huge problems in the past. Missiles overshooting targets, satellites crashing after launch, etc. Search the web for some, you'll be amazed!

Jaco Van Niekerk
  • 4,180
  • 2
  • 21
  • 48
  • 1
    Are you serious about the missiles and satellites? Or was that sarcasm? – mohdajami Nov 24 '11 at 09:00
  • 6
    http://ima.umn.edu/~arnold/455.f96/disasters.html as well as http://www.theinquirer.net/inquirer/news/1047844/floating-point-bugs-explode (just two I could find...) – Jaco Van Niekerk Nov 24 '11 at 09:34
4

This is a common pitfall with some computer representations of fractional numbers, see this question or google for floating point precision.

Community
  • 1
  • 1
zoul
  • 102,279
  • 44
  • 260
  • 354
2

Double is not the right type for very precision floating point calculations, if you want exact results you have to use BigDecimal.

Giovanni
  • 3,951
  • 2
  • 24
  • 30
  • No need to use BigDecimal in this case (which has a number of problems). It's enough to round appropriately on output. – sleske Nov 24 '11 at 08:07
  • @sleske: And what are the problems with BigDecimal? The only one I know about is performance. – bezmax Nov 24 '11 at 08:12
  • @Max: Mainly performance (CPU overhead, memory usage, and extra work for the GC), and the *very* clunky API (no way to use operators). – sleske Nov 24 '11 at 08:18
  • @Max: There are valid uses of BigDecimal. I just wanted to point out that in a simple case like this it's not really necessary, and should thus be avoided IMHO. – sleske Nov 24 '11 at 08:18