Это из-за десятичного числа, которое не может быть точно представлено в двоичном формате базы 2?
Да. В принципе, 5.4f
и 5.4d
не то же самое, потому что ни одно из них не является точным представлением 5.4.
5.5f
и 5.5d
это то же самое, поскольку они оба являются точными представлениями 5.5.
Обратите внимание, что 5.4
неявно совпадает с 5.4d
- тип по умолчанию для литерала с плавающей запятой - double
. Любое использование бинарного оператора с операндами float
и double
будет продвигать float
до double
и выполнять операцию над двумя значениями double
.
Это может облегчить представление об этом в терминах десятичных чисел типов. Предположим, что у нас было два типа: Decimal5 и Decimal10, которые являются десятичными числами с 5 или 10 значащими цифрами. Тогда рассмотрит «третью» и «четверть»:
A third:
Decimal5: 0.33333
Decimal10: 0.3333333333
A quarter (showing trailing zeroes just for clarity):
Decimal5: 0.25000
Decimal10: 0.2500000000
При сравнении значения Decimal5 ближайших к третьему со значением Decimal10, значение Decimal5 будет преобразовано в значение Decimal10 из 0.3333300000, который не делает равным 0.3333333333. Это похоже на ваш первый пример.
При сравнении значений за квартал значение Decimal5 0,25000 преобразуется в 0.2500000000, что совпадает с значением Decimal10, которое у нас есть в течение четверти. Это похоже на ваш второй пример.
Конечно, бинарные типы с плавающей запятой немного сложнее, чем при нормализации, субнормальных числах и т. Д., Но для целей вашего примера эта аналогия достаточно близка.
Много информации, просто google вокруг :) Во-первых, используйте double over float, а также см. 'BigDecimal' ... – vikingsteve
Возможный дубликат [Сравнение плавающих и двойных примитивов в Java] (http://stackoverflow.com/ вопросы/7392167/сравнение-float-and-double-primitives-in-java) – devnull
В другом вопросе это очень хорошо обсуждается http://stackoverflow.com/questions/1088216/whats-wrong-with-using-to-compare-floats -in-java – AurA