Почему это вычитание не равно нулю? - PullRequest
7 голосов
/ 05 января 2010

Я столкнулся с этими значениями в моем коде ColdFusion, но калькулятор Google, похоже, имеет ту же "ошибку", когда разница не равна нулю.

416582.2850 - 411476,8100 - 5105,475 = -2,36468622461E-011

http://www.google.com/search?hl=en&rlz=1C1GGLS_enUS340US340&q=416582.2850+-+411476.8100+-+5105.475&aq=f&oq=&aqi=

JavaCast'ы их long / float / double не помогают - это приводит к другим ненулевым различиям.

Ответы [ 7 ]

17 голосов
/ 05 января 2010

Это связано с тем, что десятичные числа, которые «выглядят» в базе 10, не совсем точно представлены в базе 2 (то, что компьютеры используют для представления чисел с плавающей запятой). Пожалуйста, смотрите статью Что должен знать каждый компьютерный ученый об арифметике с плавающей точкой для подробного объяснения этой проблемы и обходных путей.

7 голосов
/ 05 января 2010

Неточности с плавающей запятой (существует бесконечное число действительных чисел и только конечное число 32- или 64-разрядных чисел для их представления).

Если вы не можете обработать крошечные ошибки, вы должны использовать BigDecimal вместо.

6 голосов
/ 05 января 2010

Используйте PrecisionEvaluate() в ColdFusion (будет использоваться BigDecimal в Java)

zero = PrecisionEvaluate(416582.2850 - 411476.8100 - 5105.475);

в отличие от Evaulate(), "" не требуется.

2 голосов
/ 05 января 2010

Эта «ошибка» не является ошибкой. Это то, как работает арифметика с плавающей точкой. Смотри: http://docs.sun.com/source/806-3568/ncg_goldberg.html

Если вам нужна произвольная точность в Java, используйте BigDecimal:

    BigDecimal a = new BigDecimal("416582.2850");
    BigDecimal b = new BigDecimal("411476.8100");
    BigDecimal c = new BigDecimal("5105.475");
    System.out.println(a.subtract(b).subtract(c)); // 0.0
2 голосов
/ 05 января 2010

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

1 голос
/ 05 января 2010

Это проблемы с плавающей запятой, и BigDecimal исправит их.

Изменение порядка вычитания также дает ноль в Google.

416582.2850 - 5105.475 - 411476.8100 = 0
1 голос
/ 05 января 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...