Почему некорректно работает разность 2-х переменных типа double?
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double firstDouble = scanner.nextDouble();
double secondDouble = scanner.nextDouble();
if (Math.abs(secondDouble - firstDouble) < 0.000001) {
System.out.println("числа равны");
} else {
System.out.println("числа не равны");
}
System.out.println(firstDouble - secondDouble);
}
}
Имеем такой код. Просто программа проверки равенства двух вещественных чисел через сравнение их разности с 0.000001. И да, я знаю про класс java.math.BigDecimal(), но в данном случае я использую казуальный метод сравнения примитивов, но попробуйте прогнать 0.000007 и 0.000006. Казалось бы, условие не выполняется, и вывод должен быть - "не равны". Но нет. А главное, я для проверки в самом конце прописал вывод самой разности этих чисел. Там так и вовсе дичь какая-то. Уважаемые знатоки, что и почему происходит?
Ответы (1 шт):
Я запустил такой код:
public static void main(String[] args) {
double firstDouble = 0.000006;
double secondDouble = 0.000007;
System.out.println(Math.abs(secondDouble - firstDouble));
}
Казалось бы: мы должны получить 0.000001 и false. Но мы получаем 9.999999999999997E-7. Если я ничего не напутал, то это можно выразить как 0.000000999999999....
Так происходит из-за механизма хранения чисел с плавающей точкой в компьютерах. Всех тонкостей вам не расскажу, да вы можете найти их сами, скажу лишь то, что суть в следующем: в компьютерах все числа выражены в двоичной системе счисления, а не в десятичной, к какой мы привыкли, из-за чего получившееся число 0.000001 не круглое. Короче говоря, число 0.000001 не может быть полностью выражено в двоичной системе счисления, для у этого у double просто нет места, поэтому происходят такие вот ошибки.