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 place of the significand? Equivalently, this is just the greatest power of two less than or equal to the input in magnitude.
For the purposes of this question we can ignore:
- Near-overflow or near-underflow values (they can be handled with finitely many applications of
?:
to rescale). - Negative inputs (they can be handled likewise).
- Non-Annex-F-conforming implementations (can't really do anything useful in floating point with them).
- Weirdness around excess precision (
float_t
anddouble_t
can be used withFLT_EVAL_METHOD
and otherfloat.h
macros to handle it safely).
So it suffices to solve the problem for positive values bounded away from infinity and the denormal range.
Note that this problem is equivalent to finding the "epsilon" for a specific value, that is, nextafter(x,INF)-x
(or the equivalent in float
or long double
), with the result just scaled by DBL_EPSILON
(or equivalent for the type). Solutions that find that are perfectly acceptable if they're simpler.
I have a proposed solution I'm posting as a self-answer, but I'm not sure if it's correct.