Почему последний номер неверен? - PullRequest
9 голосов
/ 09 июня 2011

Почему только последний номер неверен в выходных данных этого кода:

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);


    }
}

Выходных данных:

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

Математически они эквивалентны, так что происходит?

Math.sqrt() и Math.pow(,0.5) точно так же.

Ответы [ 5 ]

16 голосов
/ 09 июня 2011

Вы не можете представлять числа с бесконечной точностью на конечном компьютере, поэтому вам нужно округлить. То, что вы видите, является эффектом округления. Это присуще любому использованию чисел с плавающей запятой.

Обязательная ссылка: Что должен знать каждый компьютерщик об арифметике с плавающей точкой

0 голосов
/ 09 июня 2011

Числа с плавающей точкой, такие как double, имеют ограниченную точность, поэтому они округляются несколько произвольно, что затрудняет некоторые операции. Я бы либо отрубил конец чисел, а затем сравнил их, либо нашел бы разницу между ними и проверил, меньше ли эта разница, чем небольшой предел погрешности (например, .0000000001)

0 голосов
/ 09 июня 2011

Ошибки округления из-за ограничений числа с плавающей / двойной.

Вы хотели бы определить какой-то предел погрешности, а затем, пока они в нем, обрабатывать их как равные.

float f = getFirst();  
float g = getSecond();  
float epsilon = 0.000005;  //Choose something suitably small
if(f-g > epsilon)  
    //equal
0 голосов
/ 09 июня 2011

Ошибки округления часто возникают при вычислениях со значениями с плавающей запятой из-за небольших различий в порядке вещей. Если бы у вас была бесконечная точность, это никогда не было бы проблемой, но компьютеры не предложат этого в ближайшее время.

Лучше всего решить, какое количество цифр точности имеет значение для вас, и обрезать или округлить ваши значения, прежде чем сравнивать их на равенство.

0 голосов
/ 09 июня 2011

Добро пожаловать в мир арифметики с плавающей точкой.Смотрите мой ответ на похожий вопрос: Десятичный порядок сложения влияет на результаты .

...