Первое я вообще не понимаю. На то, что два вычисленных идентичным образом числа могут быть не равны побитно, я когда-то давно сам налетал, но причину так окончательно и не понял (погрешность "в последнем бите" при вычислении допускает сам процессор? Но как, это же железка с жёстким алгоритмом?). Но тогда разность получается вполне разумной, порядка младшего бита мантиссы, здесь же и мантисса нулевая(?!?), и порядок ни с чем не бьётся, и "ноль (мантисса) умножить на не-ноль (порядок)" внезапно даёт не ноль...
Второй пример таки да, очевиден: конечные десятичные дроби вовсе необязательно конечны и в двоичном виде...
Comments 17
Истязайте себя Кнутом. Дональдом. Применительно к данному вопросу - т.2, гл. 4. Ну, или пособиями по численным методам.
Reply
И большинство в курсе, поэтому многие начинают забывать.
Но жизнь иногда напоминает.
В данном случае вопрос был вообще в применимости BigDecimal.ZERO.equals(valueFromModel)
Reply
Первое я вообще не понимаю. На то, что два вычисленных идентичным образом числа могут быть не равны побитно, я когда-то давно сам налетал, но причину так окончательно и не понял (погрешность "в последнем бите" при вычислении допускает сам процессор? Но как, это же железка с жёстким алгоритмом?). Но тогда разность получается вполне разумной, порядка младшего бита мантиссы, здесь же и мантисса нулевая(?!?), и порядок ни с чем не бьётся, и "ноль (мантисса) умножить на не-ноль (порядок)" внезапно даёт не ноль...
Второй пример таки да, очевиден: конечные десятичные дроби вовсе необязательно конечны и в двоичном виде...
Reply
BigDecimal one = new BigDecimal(1.001);
BigDecimal two = new BigDecimal(1.001);
System.out.println(one); // 1.000999999999999889865875957184471189975738525390625
System.out.println(two); // 1.000999999999999889865875957184471189975738525390625
System.out.println(one.equals(two)); // true
BigDecimal three = one.subtract(two);
System.out.println(three); // 0E-51
System.out.println(BigDecimal.ZERO.equals(three)); // false
Числа one и two равны, но их разность не равна нулю.
Reply
Leave a comment