Число с плавающей запятой одинарной точности содержит 23 значащих и битов , а не значащих и десятичных цифр.
Чтобы узнать, как округляются значения, будет проще увидеть их при записи в двоичном виде:
₁₂₃₄₅₆₇₈₉₀¹²³⁴⁵⁶⁷⁸⁹⁰₁₂₃₄₅₆₇₈₉₀
1000000000 = 111011100110101100101000000000 (0x4e6e6b28)
1000000032 = 111011100110101100101000100000
1000000033 = 111011100110101100101000100001
1000000064 = 111011100110101100101001000000 (0x4e6e6b29)
Truncated ^^^^^^
Normalized: 1.11011100110101100101000 x 2²⁹
Когда показатель степени равен 29, закрывающими представлениями этих значений являются 1000000000 и 1000000064, которые сохраняются как 0x4e6e6b28
и 0x4e6e6b29
соответственно с одинарной точностью. Как видите, они отличаются только на один бит в последней позиции
Таким образом, когда мы преобразуем 1000000032 и 1000000033 в 24 бита значащих, сначала 6 последних бит усекаются, а затем применяется правильное округление. В случае 1000000033 легко увидеть, что оно ближе к следующему представляемому значению (1 000 000 064
), чем предыдущее (1 000 000 000
), поэтому, конечно, оно будет округлено. Однако 1000000032 находится точно посередине между этими значениями, поэтому от реализации зависит выбор одного из разрешенных режимов округления, определенных стандартом IEEE-754:
Стандарт определяет пять правил округления. Первые два правила округляются до ближайшего значения; остальные называются направленными округлениями:
Округления до ближайшего
- Округление до ближайшего, привязка к четному - округление до ближайшего значения; если число падает на полпути, оно округляется до ближайшего значения с четным (нулевым) младшим значащим битом; это значение по умолчанию для двоичной с плавающей запятой и рекомендуемое значение по умолчанию для десятичного числа .
- Округление до ближайшего, связывает от нуля - округляет до ближайшего значения; если число падает на полпути, оно округляется до ближайшего значения выше (для положительных чисел) или ниже (для отрицательных чисел); это задано как опция для десятичной плавающей запятой.
https://en.wikipedia.org/wiki/IEEE_754#Rounding_rules
Похоже, здесь используется рекомендуемое привязка к четному . Точно так же 1000000096 будет округлено до 1000000128 из-за связи с четным правилом
Вы можете посмотреть в поле Error due to conversion
и увидеть, что ошибка составляет -32, 31 и 32 для 1000000032, 1000000033 и 1000000096 соответственно
Вы также можете попробовать Изучение преобразователя Binary , который дает более полезные представления и четко определяет, как он округляет значение
Это десятичный в двоичный преобразователь с плавающей запятой. Он преобразует десятичное число в ближайшее двоичное число с плавающей запятой IEEE 754 одинарной и двойной точности, используя округление от половины до четного (режим округления по умолчанию IEEE) . Он реализован с арифметикой произвольной точности, поэтому его преобразования правильно округлены. Он преобразует как нормальные, так и субнормальные числа и преобразует числа, которые переполнены (в бесконечность) или меньше (в ноль).