-2

I was trying Math.pow on 1.09 to calculate the square. I was getting 1.1881000000000002 as result and when I tried 1.09*1.09 it was also giving the same result.

Any idea why I am getting this?

Java env details- java version "1.6.0_38" Java(TM) SE Runtime Environment (build 1.6.0_38-b05) Java HotSpot(TM) 64-Bit Server VM (build 20.13-b02, mixed mode)

Any fixes??

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Checkout this class http://docs.oracle.com/javase/1.5.0/docs/api/java/math/BigDecimal.html#pow(int) – Jason Sperske Oct 06 '13 at 04:53
  • This is due to representations of floating point numbers which will cause such discrepencies in any languages which natively store floating point numbers in binary. For more information look here: http://floating-point-gui.de/basic/. For a "fix" look here: http://stackoverflow.com/questions/277309/java-floating-point-high-precision-library – sushain97 Oct 06 '13 at 04:54
  • 10
    [What every cs should know about floating arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – nachokk Oct 06 '13 at 04:54
  • 1
    There is a much larger answer that I'm sure someone else is typing right now involving floating point numbers and something called the mantissa – Jason Sperske Oct 06 '13 at 04:55

3 Answers3

5

That's just how floating point numbers are, unfortunately. A floating point variable can hold an unbelievably large range in only a few bytes, so you have to trade off precision.

Why does it matter that your number is off by .0000000000000002? I really doubt that your precision matters that much. Are you more concerned with the formatting? If so, use format strings.

If you want to ensure that the same rather unexpected behavior works equally on all platforms, use the strictfp keyword.

Hut8
  • 6,080
  • 4
  • 42
  • 59
2

Math.pow is very slow, so I wouldn't use it unless you have to. Floating point cannot represent most decimal number accurately. Instead they store the nearest representable value. When you print this value it assumes you want the shortest decimal which has this representation i.e. it hides the error.

However, when you perform calculations, this error can be exposed. This is when you must apply reasonable rounding to the result. e.g.

double d = 1.09;
System.out.printf("%.4f%n", d * d);

prints

1.1881
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

Floating point multiplication isn't perfect.

A floating point number is only 32 bits (64 for a double), and so there are only 2^32 or 2^64 states that it can represent -- rather fewer than there are real numbers in the range you're looking at.

Thus, when you do any computation, there's some rounding that's going to happen because of this. Sometimes it's closer than others. It just so happens that the closest floating point number to 1.881 is 1.881000000000002, and so that's the result that you get when you do a computation that should give you 1.881.

qaphla
  • 4,707
  • 3
  • 20
  • 31
  • I am executing expression at run time using JEval and I can not set precision. Is there a way I can set precision for a method. I tried strictfp as well but getting same result – Shiveendra Siingh Oct 06 '13 at 05:20
  • If you need this kind of precision (such as for banking or scientific purposes), you'll have to do your calculations with the BigDecimal class and its children. Or check out the StackOverflow link in the comment on your post – Sebastiaan van den Broek Oct 06 '13 at 07:49