aboutsummaryrefslogtreecommitdiff
path: root/libc/src/__support/FPUtil/ManipulationFunctions.h
diff options
context:
space:
mode:
Diffstat (limited to 'libc/src/__support/FPUtil/ManipulationFunctions.h')
-rw-r--r--libc/src/__support/FPUtil/ManipulationFunctions.h10
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);
}