The problem: given a floating point constant expression, can we write a macro that evaluates to a constant expression whose value is a power of two equal to the most significant
If you can assume IEEE 754 binary64 format and semantics (and in particular that arithmetic operations are correctly rounded), and a round-ties-to-even rounding mode, then it's a nice fact that for any not-too-small not-too-large positive finite double
value x
, the next representable value up from x
is always given by x / 0x1.fffffffffffffp-1
(where 0x1.fffffffffffffp-1
is just 1.0 - 0.5 * DBL_EPSILON
spelled out as a hex literal).
So we can get the most significant bit that you ask for simply from:
(x / 0x1.fffffffffffffp-1 - x) * 0x1.0p+52
And of course there are analogous results for float
, assuming IEEE 754 binary32 format and semantics.
In fact, the only normal positive value that this fails for is DBL_MAX
, where the result of the division overflows to infinity.
To show that the division trick works, it's enough to prove it for x
in the range 1.0 <= x < 2.0
; it's easy to show that for any x
in this range, the value of x / 0x1.fffffffffffffp-1 - x
(where /
represents mathematical division in this case) lies in the half-open interval (2^-53, 2^52]
, and it follows that under round-ties-to-even (or in fact any round-to-nearest rounding mode), x / 0x1.fffffffffffffp-1
rounds up to the next representable value.
Similarly, under the same assumptions, x * 0x1.fffffffffffffp-1
is always the next representable value down from x
.