diff options
Diffstat (limited to 'libc/src/__support/FPUtil/ManipulationFunctions.h')
-rw-r--r-- | libc/src/__support/FPUtil/ManipulationFunctions.h | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h index a289c2e..97c4312 100644 --- a/libc/src/__support/FPUtil/ManipulationFunctions.h +++ b/libc/src/__support/FPUtil/ManipulationFunctions.h @@ -142,8 +142,10 @@ LIBC_INLINE constexpr T logb(T x) { return static_cast<T>(normal.get_unbiased_exponent()); } -template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0> -LIBC_INLINE constexpr T ldexp(T x, int exp) { +template <typename T, typename U> +LIBC_INLINE constexpr cpp::enable_if_t< + cpp::is_floating_point_v<T> && cpp::is_integral_v<U>, T> +ldexp(T x, U exp) { FPBits<T> bits(x); if (LIBC_UNLIKELY((exp == 0) || bits.is_zero() || bits.is_inf_or_nan())) return x; @@ -156,6 +158,8 @@ LIBC_INLINE constexpr T ldexp(T x, int exp) { // calculating the limit. constexpr int EXP_LIMIT = FPBits<T>::MAX_BIASED_EXPONENT + FPBits<T>::FRACTION_LEN + 1; + // Make sure that we can safely cast exp to int when not returning early. + static_assert(EXP_LIMIT <= INT_MAX && -EXP_LIMIT >= INT_MIN); if (LIBC_UNLIKELY(exp > EXP_LIMIT)) { int rounding_mode = quick_get_round(); Sign sign = bits.sign(); @@ -186,7 +190,7 @@ LIBC_INLINE constexpr T ldexp(T x, int exp) { // For all other values, NormalFloat to T conversion handles it the right way. DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val()); - normal.exponent += exp; + normal.exponent += static_cast<int>(exp); return static_cast<T>(normal); } |