0

Why do I get strange results when subtracting 2.99999... from 3?

scala> math.sqrt(3)
res0: Double = 1.7320508075688772

scala> math.pow(res0, 2)
res1: Double = 2.9999999999999996

scala> 3 - res1
res2: Double = 4.440892098500626E-16
Omar Wagih
  • 8,504
  • 7
  • 59
  • 75
WelcomeTo
  • 19,843
  • 53
  • 170
  • 286
  • 3
    looks ok to me. what's strange about it? – Nathan Hughes Jun 07 '13 at 13:28
  • 2
    Note `...E-16` at the end. It is *very* tiny difference (a little more than 0000000000000000.1). – om-nom-nom Jun 07 '13 at 13:30
  • 1
    If you want uber precision you should consider using [apfloat](http://www.apfloat.org/apfloat_java/) (but even that gives no guarantee of a zero result) – fge Jun 07 '13 at 13:31
  • 1
    How much precision to you want? To put things in perspective, to be accurate within E-16 is like specifying the distance of the sun from Pluto in mm and worrying about decimal places, hardly something to haggle over? – Bathsheba Jun 07 '13 at 13:46
  • BTW this isn't unique to Scala. Go try this in any other programming language and you should get a similar result. This is a fundamental limitation of how your hardware does floating-point calculations. – DaoWen Jun 07 '13 at 15:29

2 Answers2

7

This is due to floating point precision; well documented in What range of numbers can be represented in a 16-, 32- and 64-bit IEEE-754 systems?

Also, its worth noting here that there is no way the perfect computer could represent sqrt(3) in decimal as it's irrational!

Did you really think that sqrt(3) equals exactly 1.7320508075688772?

Community
  • 1
  • 1
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 2
    +1 for actually referencing floating-point limitations. Doubles are 64 bits. You're not going to be able to accurately represent an [irrational number](http://en.wikipedia.org/wiki/Irrational_number) in any finite number of bits—period. – DaoWen Jun 07 '13 at 15:28
3

This is exponential notation. 4 times 10^(-16) looks correct to me (within the limits of floating point accuracy).

Rob Lyndon
  • 12,089
  • 5
  • 49
  • 74