Если , вы можете принять формат двоичной64 IEEE 754 и семантику (и, в частности, правильное округление арифметических операций) и режим округления с округлением до четности, то это хороший факт, что длялюбое не слишком маленькое не слишком большое положительное конечное double
значение x
, следующее представимое значение по сравнению с x
всегда задается как x / 0x1.fffffffffffffp-1
(где 0x1.fffffffffffffp-1
- это просто 1.0 - 0.5 * DBL_EPSILON
, обозначенное какшестнадцатеричный литерал).
Таким образом, мы можем получить наиболее значимый бит, который вы запрашиваете просто:
(x / 0x1.fffffffffffffp-1 - x) * 0x1.0p+52
И, конечно, есть аналогичные результаты для float
, предполагая IEEE 754Формат и семантика binary32.
Фактически, единственное нормальное положительное значение, для которого это не удается, - DBL_MAX
, где результат деления переполняется до бесконечности.
Чтобы показать, что трюк деленияработает, достаточно доказать это для x
в диапазоне 1.0 <= x < 2.0
;Легко показать, что для любого x
в этом диапазоне значение x / 0x1.fffffffffffffp-1 - x
(где /
представляет математическое деление в этом случае) лежит в полуоткрытом интервале (2^-53, 2^52]
, и из этого следует, что при округлениисвязь до четного (или фактически любой режим округления до ближайшего), x / 0x1.fffffffffffffp-1
округляет до следующего представимого значения.
Аналогично, при тех же предположениях, x * 0x1.fffffffffffffp-1
всегда является следующимпредставительное значение по сравнению с x
.