9

Why is only the last number wrong in the output this code:

public class Test {
    public static void main(String[] args) {
        System.out.println("Hello world");
        System.out.println("I wounder is the sqaure root of (2*3) the 
                           same as the sqaure root of 2 and 3 multiplied.");
        double squareroot0 = Math.pow(3*2, 0.5);
        double squarroot1 = (Math.pow(3, 0.5) * Math.pow(2, 0.5)); 
        System.out.println("So is it the same?");

        System.out.println("is " + squareroot0 + " the equvielant of " + 
                                               squarroot1 + "?");
        if(squareroot0 == squarroot1) {
            System.out.println("Yes number one and number two are 
                                               the same, Congrats!");
        }else {
            System.out.println("No they are not! ");
        }

        System.out.println(squareroot0);
        System.out.println(squarroot1);


    }
}

Output:

Hello world
I wonder is the sqaure root of (2*3) the same as the sqaure 
root of 2 and 3 multiplied.
So is it the same?
is 2.449489742783178 the equvielant of 2.4494897427831783?
No they are not! 
2.449489742783178
2.4494897427831783

Mathematically they are equivalent, so what is going on?

Math.sqrt() and Math.pow(,0.5) is just as accurate.

Alvar
  • 252
  • 1
  • 4
  • 13
  • http://stackoverflow.com/questions/753948/why-is-floating-point-arithmetic-in-c-imprecise – heisenberg Jun 09 '11 at 13:53
  • Hi Alvar - just a quick note - for small code samples like that you're absolutely fine including them in your question. I've included the code from your pastebin for you. –  Jun 09 '11 at 13:55
  • it looks great now thanks! not used to implanting code in a question, I'm used to askubuntu.com... – Alvar Jun 09 '11 at 13:59
  • @Alvar, both numbers are wrong, just an approximation, one has an extra digit of accuracy. BTW square is mis-spelt. ;) – Peter Lawrey Jun 09 '11 at 14:05
  • @Alvar using `Math.sqrt()` will be faster and possibly more accurate than `Math.pow(x, 0.5)` – Peter Lawrey Jun 09 '11 at 14:06
  • BTW wonder is miss spelled in the code but not in the output. I have an idea, an updated version will come... – Alvar Jun 09 '11 at 14:35
  • Version 2.0 ;) http://paste.ubuntu.com/622856/ – Alvar Jun 09 '11 at 20:37

4 Answers4

16

You can't represent numbers with infinite precision in a finite computer, so you need to round. What you see is the effect of rounding. This is inherent to all uses of floating point numbers.

Mandatory link: What Every Computer Scientist Should Know About Floating-Point Arithmetic

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • +1 for the goldberg paper. A must read for any serious CS person – Voo Jun 09 '11 at 14:00
  • So does my computer/Java round up an answer inside an operation? because I wonder what is the correct answer here? – Alvar Jun 09 '11 at 14:02
  • @Alvar: Neither of the two is the exact answer. Both are rounded. The exact answer has infinitely many decimal places. – Sven Marnach Jun 09 '11 at 14:07
  • True, but which one is the most correct, (well, both are wrong but still.) – Alvar Jun 09 '11 at 14:31
  • @Alvar: [Compare yourself](http://www.wolframalpha.com/input/?i=sqrt%286%29). The first version is better since it needs to round only once, whereas the second version includes three inexact steps. – Sven Marnach Jun 09 '11 at 14:51
  • This is what I wanted to proof! http://www.wolframalpha.com/input/?i=sqrt%283%29*sqrt%282%29 – Alvar Jun 09 '11 at 17:25
  • is there a way get good results even if you have 5 steps or so? – Alvar Jun 09 '11 at 19:33
  • @Alvar, there are some rules of thumb, like beware of taking using the difference between two numbers that are close to each other, and beware adding a large number to a small number, but it really depends on the exact nature of the problem. In fact there is an entire subfield of mathematics, numerical analysis (http://en.wikipedia.org/wiki/Numerical_analysis), largely devoted to finding ways to minimize the impact of rounding errors and other effects of our approximate representation of numbers. – Charles E. Grant Jun 10 '11 at 03:08
0

Rounding errors occur frequently when computing with floating point values, due to slight differences in the order of things. If you had infinite precision this would never be a problem, but computers won't offer that any time soon.

Your best bet is to decide the number of digits of precision that matter to you and clip or round your values before comparing them for equality.

mah
  • 39,056
  • 9
  • 76
  • 93
0

Rounding errors due to limitations of float/double.

You'd want to define some margin of error, then so long as they're within it, treat them as equal.

float f = getFirst();  
float g = getSecond();  
float epsilon = 0.000005;  //Choose something suitably small
if(f-g > epsilon)  
    //equal
Sysyphus
  • 1,061
  • 5
  • 10
0

Floating point numbers like doubles have limited precision, so they round somewhat arbitrarily, which makes some operations difficult. I would either chop off the end of the numbers and then compare them, or find the difference between them and check if that difference is less than a small margin of error (e.g. .0000000001)

carlbenson
  • 3,177
  • 5
  • 35
  • 54