Ответ 1
Кажется, что ни один из ответов не имеет отношения к , почему 17.32
действует иначе.
1. Почему это произошло
Разница в поведении между 17.32
и 17.33 & 17.31
обусловлена правилами IEEE-754 Rounding.
Используется правило округления: from, Виртуальный Java ™ Спецификация станка §2.8.1
Операции округления виртуальной машины Java всегда используют IEEE 754 до ближайшего режима. Неточные результаты округлены до ближайшего представляемое значение, с привязкой к значению с нулем младший бит. Это режим по умолчанию IEEE 754. Виртуальный виртуальный Java машина не дает никаких средств для изменения округления с плавающей запятой Режим
2. Ваш случай:
Двойной: (1 знаковый бит + 11 экспоненциальных битов + 52 дробных разряда = 64 бит). Внутреннее представление после округления ниже:
1 [63] 11 [62-52] 52 [51-00]
Sign Exponent Fraction
17.31 --> 0 (+) 10000000011 (+4) 1.0001010011110101110000101000111101011100001010001111
17.32 --> 0 (+) 10000000011 (+4) 1.0001010100011110101110000101000111101011100001010010 //rounded up
17.33 --> 0 (+) 10000000011 (+4) 1.0001010101000111101011100001010001111010111000010100
3. Внутреннее представление (Доказательство):
17.31: (сравнение Мантиссы)
Actual: 1.00010100111101011100001010001111010111000010100011110...
Internal: 1.0001010011110101110000101000111101011100001010001111
17.32: (сравнение Мантиссы)
Actual: 1.00010101000111101011100001010001111010111000010100011...
Internal: 1.0001010100011110101110000101000111101011100001010010 //round-up!
17.33: (сравнение Мантиссы)
Actual: 1.00010101010001111010111000010100011110101110000101000...
Internal: 1.0001010101000111101011100001010001111010111000010100
4. Преобразование обратно в десятичное:
17.31 -> 17.309999999999998721023075631819665431976318359375...
17.32 -> 17.32000000000000028421709430404007434844970703125... //(was rounded up)
17.33 -> 17.3299999999999982946974341757595539093017578125...
5. Вставить в длинный
РЕДАКТИРОВАТЬ: На шаге умножения есть фактор, который, как сказал @Jeppe Стиг Нильсен, сказал: Результат умножения FP (Ссылка) делает свое собственное округление - ближайший. Это изменяет результаты, как ожидалось, а какие нет, но причина по-прежнему такая же, как указано выше.
Наконец, из-за литого (long)
происходит усечение и оставляет вас с результатами, которые вы видите. (1730, 1732, 1732)
Сужение примитивного преобразования: Спецификация языка Java ™ §5.1.3
Если число с плавающей запятой не является бесконечным, точка с плавающей запятой значение округляется до целочисленного значения V, округляя до нуля, используя Режим IEEE 754 с округлением до нуля