Avoid right-shifting a negative value in detail::power()

This commit is contained in:
Sahana Bogar 2026-10-14 23:46:38 +05:30
parent 166d2b3df2
commit 90513adca1

View File

@ -61,9 +61,15 @@ namespace detail {
* -ceil(p) + q * -ceil(p) + q
* where * where
* p = log(5**-q)/log(2) = -q * log(5)/log(2) * p = log(5**-q)/log(2) = -q * log(5)/log(2)
*
* The shift must floor towards negative infinity, as an arithmetic right
* shift does, but right-shifting a negative value is implementation-defined
* before C++20. Biasing the product by 2048 * 65536 keeps the shifted value
* non-negative without changing the result: the bias is a multiple of 2^16
* and is removed again after the shift.
*/ */
constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept { constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept {
return (((152170 + 65536) * q) >> 16) + 63; return (((152170 + 65536) * q + (2048 * 65536)) >> 16) - 2048 + 63;
} }
} // namespace detail } // namespace detail