[libc-commits] [libc] [libc][NFC] Remove `FPBits` cast operator (PR #79142)

Guillaume Chatelet via libc-commits libc-commits at lists.llvm.org
Tue Jan 23 08:16:54 PST 2024


https://github.com/gchatelet updated https://github.com/llvm/llvm-project/pull/79142

>From 43c662337fa7e16e1f28314a9f8b7aade02cd8fe Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Tue, 23 Jan 2024 14:28:02 +0000
Subject: [PATCH 1/2] [libc][NFC] Remove `FPBits` cast operator

---
 libc/src/__support/FPUtil/BasicOperations.h   |  2 +-
 .../FPUtil/DivisionAndRemainderOperations.h   |  2 +-
 libc/src/__support/FPUtil/FPBits.h            |  2 -
 libc/src/__support/FPUtil/Hypot.h             | 10 ++---
 .../__support/FPUtil/ManipulationFunctions.h  | 14 +++----
 .../FPUtil/NearestIntegerOperations.h         | 14 +++----
 libc/src/__support/FPUtil/NormalFloat.h       | 14 +++----
 libc/src/__support/FPUtil/generic/FMA.h       |  8 ++--
 libc/src/__support/str_to_float.h             |  8 ++--
 libc/src/math/generic/exp.cpp                 |  2 +-
 libc/src/math/generic/exp10.cpp               |  2 +-
 libc/src/math/generic/exp2.cpp                |  2 +-
 libc/src/math/generic/expf.cpp                |  2 +-
 libc/src/math/generic/hypotf.cpp              |  6 +--
 libc/src/math/generic/log10f.cpp              |  2 +-
 libc/src/math/generic/log1pf.cpp              |  4 +-
 libc/src/math/generic/log2f.cpp               |  2 +-
 libc/src/math/generic/logf.cpp                |  4 +-
 libc/src/math/generic/range_reduction_fma.h   |  4 +-
 .../stdio/printf_core/float_dec_converter.h   |  6 +--
 libc/test/UnitTest/FPMatcher.h                | 40 +++++++++----------
 libc/test/src/math/CeilTest.h                 |  2 +-
 libc/test/src/math/CopySignTest.h             |  2 +-
 libc/test/src/math/FAbsTest.h                 |  2 +-
 libc/test/src/math/FDimTest.h                 | 12 +++---
 libc/test/src/math/FMaxTest.h                 |  2 +-
 libc/test/src/math/FMinTest.h                 |  2 +-
 libc/test/src/math/FloorTest.h                |  2 +-
 libc/test/src/math/FmaTest.h                  | 28 ++++++-------
 libc/test/src/math/FrexpTest.h                |  2 +-
 libc/test/src/math/HypotTest.h                | 22 +++++-----
 libc/test/src/math/ILogbTest.h                | 14 +++----
 libc/test/src/math/LdExpTest.h                | 10 ++---
 libc/test/src/math/LogbTest.h                 |  2 +-
 libc/test/src/math/ModfTest.h                 |  2 +-
 libc/test/src/math/NextAfterTest.h            | 10 ++---
 libc/test/src/math/RIntTest.h                 | 14 +++----
 libc/test/src/math/RemQuoTest.h               | 14 +++----
 libc/test/src/math/RoundTest.h                |  2 +-
 libc/test/src/math/RoundToIntegerTest.h       | 18 ++++-----
 libc/test/src/math/SqrtTest.h                 |  2 +-
 libc/test/src/math/TruncTest.h                |  2 +-
 libc/test/src/math/acosf_test.cpp             |  4 +-
 libc/test/src/math/acoshf_test.cpp            |  4 +-
 libc/test/src/math/asinf_test.cpp             |  4 +-
 libc/test/src/math/asinhf_test.cpp            |  4 +-
 libc/test/src/math/atanf_test.cpp             |  4 +-
 libc/test/src/math/atanhf_test.cpp            |  6 +--
 libc/test/src/math/cos_test.cpp               |  2 +-
 libc/test/src/math/cosf_test.cpp              |  6 +--
 libc/test/src/math/coshf_test.cpp             | 12 +++---
 libc/test/src/math/erff_test.cpp              |  2 +-
 .../src/math/exhaustive/exhaustive_test.h     |  7 ++--
 libc/test/src/math/exhaustive/hypotf_test.cpp |  4 +-
 .../test/src/math/exhaustive/sincosf_test.cpp |  2 +-
 libc/test/src/math/exp10_test.cpp             |  2 +-
 libc/test/src/math/exp10f_test.cpp            | 17 ++++----
 libc/test/src/math/exp2_test.cpp              |  2 +-
 libc/test/src/math/exp2f_test.cpp             | 18 ++++-----
 libc/test/src/math/exp_test.cpp               |  2 +-
 libc/test/src/math/expf_test.cpp              | 24 +++++------
 libc/test/src/math/expm1_test.cpp             |  2 +-
 libc/test/src/math/expm1f_test.cpp            | 30 +++++++-------
 libc/test/src/math/log10_test.cpp             |  2 +-
 libc/test/src/math/log10f_test.cpp            |  4 +-
 libc/test/src/math/log1p_test.cpp             |  2 +-
 libc/test/src/math/log1pf_test.cpp            |  4 +-
 libc/test/src/math/log2_test.cpp              |  2 +-
 libc/test/src/math/log2f_test.cpp             |  4 +-
 libc/test/src/math/log_test.cpp               |  2 +-
 libc/test/src/math/logf_test.cpp              |  4 +-
 libc/test/src/math/sin_test.cpp               |  2 +-
 libc/test/src/math/sincosf_test.cpp           |  6 +--
 libc/test/src/math/sinf_test.cpp              | 10 ++---
 libc/test/src/math/sinhf_test.cpp             | 16 ++++----
 libc/test/src/math/smoke/FDimTest.h           | 12 +++---
 libc/test/src/math/smoke/FMaxTest.h           |  2 +-
 libc/test/src/math/smoke/FMinTest.h           |  2 +-
 libc/test/src/math/smoke/FmaTest.h            | 24 +++++------
 libc/test/src/math/smoke/HypotTest.h          | 20 +++++-----
 libc/test/src/math/smoke/ILogbTest.h          | 14 +++----
 libc/test/src/math/smoke/LdExpTest.h          | 10 ++---
 libc/test/src/math/smoke/LogbTest.h           |  2 +-
 libc/test/src/math/smoke/ModfTest.h           |  2 +-
 libc/test/src/math/smoke/NextAfterTest.h      | 10 ++---
 libc/test/src/math/smoke/NextTowardTest.h     | 10 ++---
 libc/test/src/math/smoke/RIntTest.h           | 10 ++---
 libc/test/src/math/smoke/RemQuoTest.h         | 10 ++---
 libc/test/src/math/smoke/RoundToIntegerTest.h | 12 +++---
 libc/test/src/math/smoke/coshf_test.cpp       |  6 +--
 libc/test/src/math/smoke/exp10f_test.cpp      |  6 +--
 libc/test/src/math/smoke/exp2f_test.cpp       |  6 +--
 libc/test/src/math/smoke/expf_test.cpp        |  6 +--
 libc/test/src/math/smoke/expm1f_test.cpp      |  6 +--
 libc/test/src/math/smoke/sinhf_test.cpp       | 10 ++---
 libc/test/src/math/tan_test.cpp               |  2 +-
 libc/test/src/math/tanf_test.cpp              |  6 +--
 libc/test/src/math/tanhf_test.cpp             |  4 +-
 libc/test/src/stdlib/atof_test.cpp            |  2 +-
 libc/test/src/stdlib/strtod_test.cpp          |  5 +--
 libc/test/src/stdlib/strtof_test.cpp          |  2 +-
 libc/utils/MPFRWrapper/MPFRUtils.cpp          |  2 +-
 102 files changed, 366 insertions(+), 369 deletions(-)

diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index ea78809dfc7f7d5..ccc61a89c5f831f 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -21,7 +21,7 @@ template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
 LIBC_INLINE T abs(T x) {
   FPBits<T> bits(x);
   bits.set_sign(Sign::POS);
-  return T(bits);
+  return bits.get_val();
 }
 
 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
diff --git a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
index 2859a248b95e390..5f542f65035591c 100644
--- a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
+++ b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
@@ -86,7 +86,7 @@ LIBC_INLINE T remquo(T x, T y, int &q) {
   // then the conversion to native remainder value should be updated
   // appropriately and some directed tests added.
   T native_remainder(remainder);
-  T absy = T(ybits);
+  T absy = ybits.get_val();
   int cmp = remainder.mul2(1).cmp(normaly);
   if (cmp > 0) {
     q = q + 1;
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 0a79b505ecbe1c2..e43c6168f1f47b2 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -727,8 +727,6 @@ struct FPBits final : public internal::FPRep<get_fp_type<T>(), FPBits<T>> {
   // Floating-point conversions.
   LIBC_INLINE constexpr T get_val() const { return cpp::bit_cast<T>(bits); }
 
-  LIBC_INLINE constexpr explicit operator T() const { return get_val(); }
-
   // TODO: Use an uint32_t for 'biased_exp'.
   LIBC_INLINE static constexpr FPBits<T>
   create_value(Sign sign, StorageType biased_exp, StorageType mantissa) {
diff --git a/libc/src/__support/FPUtil/Hypot.h b/libc/src/__support/FPUtil/Hypot.h
index 82237dec09e42e3..2e699657346446f 100644
--- a/libc/src/__support/FPUtil/Hypot.h
+++ b/libc/src/__support/FPUtil/Hypot.h
@@ -111,7 +111,7 @@ LIBC_INLINE T hypot(T x, T y) {
   FPBits_t x_bits(x), y_bits(y);
 
   if (x_bits.is_inf() || y_bits.is_inf()) {
-    return T(FPBits_t::inf());
+    return FPBits_t::inf().get_val();
   }
   if (x_bits.is_nan()) {
     return x;
@@ -196,8 +196,8 @@ LIBC_INLINE T hypot(T x, T y) {
       if (out_exp >= FPBits_t::MAX_BIASED_EXPONENT) {
         if (int round_mode = quick_get_round();
             round_mode == FE_TONEAREST || round_mode == FE_UPWARD)
-          return T(FPBits_t::inf());
-        return T(FPBits_t::max_normal());
+          return FPBits_t::inf().get_val();
+        return FPBits_t::max_normal().get_val();
       }
     } else {
       // For denormal result, we simply move the leading bit of the result to
@@ -253,8 +253,8 @@ LIBC_INLINE T hypot(T x, T y) {
     ++out_exp;
     if (out_exp >= FPBits_t::MAX_BIASED_EXPONENT) {
       if (round_mode == FE_TONEAREST || round_mode == FE_UPWARD)
-        return T(FPBits_t::inf());
-      return T(FPBits_t::max_normal());
+        return FPBits_t::inf().get_val();
+      return FPBits_t::max_normal().get_val();
     }
   }
 
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index d7114625a9b3141..56e53e3d4f497cf 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -49,13 +49,13 @@ LIBC_INLINE T modf(T x, T &iptr) {
     return x;
   } else if (bits.is_inf()) {
     iptr = x;
-    return T(FPBits<T>::zero(bits.sign()));
+    return FPBits<T>::zero(bits.sign()).get_val();
   } else {
     iptr = trunc(x);
     if (x == iptr) {
       // If x is already an integer value, then return zero with the right
       // sign.
-      return T(FPBits<T>::zero(bits.sign()));
+      return FPBits<T>::zero(bits.sign()).get_val();
     } else {
       return x - iptr;
     }
@@ -66,7 +66,7 @@ template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
 LIBC_INLINE T copysign(T x, T y) {
   FPBits<T> xbits(x);
   xbits.set_sign(FPBits<T>(y).sign());
-  return T(xbits);
+  return xbits.get_val();
 }
 
 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
@@ -103,12 +103,12 @@ LIBC_INLINE T logb(T x) {
   if (bits.is_zero()) {
     // TODO(Floating point exception): Raise div-by-zero exception.
     // TODO(errno): POSIX requires setting errno to ERANGE.
-    return T(FPBits<T>::inf(Sign::NEG));
+    return FPBits<T>::inf(Sign::NEG).get_val();
   } else if (bits.is_nan()) {
     return x;
   } else if (bits.is_inf()) {
     // Return positive infinity.
-    return T(FPBits<T>::inf());
+    return FPBits<T>::inf().get_val();
   }
 
   NormalFloat<T> normal(bits);
@@ -131,11 +131,11 @@ LIBC_INLINE T ldexp(T x, int exp) {
   // calculating the limit.
   int exp_limit = FPBits<T>::MAX_BIASED_EXPONENT + FPBits<T>::FRACTION_LEN + 1;
   if (exp > exp_limit)
-    return T(FPBits<T>::inf(bits.sign()));
+    return FPBits<T>::inf(bits.sign()).get_val();
 
   // Similarly on the negative side we return zero early if |exp| is too small.
   if (exp < -exp_limit)
-    return T(FPBits<T>::zero(bits.sign()));
+    return FPBits<T>::zero(bits.sign()).get_val();
 
   // For all other values, NormalFloat to T conversion handles it the right way.
   NormalFloat<T> normal(bits);
diff --git a/libc/src/__support/FPUtil/NearestIntegerOperations.h b/libc/src/__support/FPUtil/NearestIntegerOperations.h
index 62568977dc0c8b1..19ae75ea7889127 100644
--- a/libc/src/__support/FPUtil/NearestIntegerOperations.h
+++ b/libc/src/__support/FPUtil/NearestIntegerOperations.h
@@ -41,11 +41,11 @@ LIBC_INLINE T trunc(T x) {
 
   // If the exponent is such that abs(x) is less than 1, then return 0.
   if (exponent <= -1)
-    return T(FPBits<T>::zero(bits.sign()));
+    return FPBits<T>::zero(bits.sign()).get_val();
 
   int trim_size = FPBits<T>::FRACTION_LEN - exponent;
   bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
-  return T(bits);
+  return bits.get_val();
 }
 
 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
@@ -73,7 +73,7 @@ LIBC_INLINE T ceil(T x) {
 
   uint32_t trim_size = FPBits<T>::FRACTION_LEN - exponent;
   bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
-  T trunc_value = T(bits);
+  T trunc_value = bits.get_val();
 
   // If x is already an integer, return it.
   if (trunc_value == x)
@@ -114,19 +114,19 @@ LIBC_INLINE T round(T x) {
 
   if (exponent == -1) {
     // Absolute value of x is greater than equal to 0.5 but less than 1.
-    return T(FPBits<T>::one(bits.sign()));
+    return FPBits<T>::one(bits.sign()).get_val();
   }
 
   if (exponent <= -2) {
     // Absolute value of x is less than 0.5.
-    return T(FPBits<T>::zero(bits.sign()));
+    return FPBits<T>::zero(bits.sign()).get_val();
   }
 
   uint32_t trim_size = FPBits<T>::FRACTION_LEN - exponent;
   bool half_bit_set =
       bool(bits.get_mantissa() & (StorageType(1) << (trim_size - 1)));
   bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
-  T trunc_value = T(bits);
+  T trunc_value = bits.get_val();
 
   // If x is already an integer, return it.
   if (trunc_value == x)
@@ -180,7 +180,7 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
   uint32_t trim_size = FPBits<T>::FRACTION_LEN - exponent;
   FPBits<T> new_bits = bits;
   new_bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
-  T trunc_value = T(new_bits);
+  T trunc_value = new_bits.get_val();
 
   // If x is already an integer, return it.
   if (trunc_value == x)
diff --git a/libc/src/__support/FPUtil/NormalFloat.h b/libc/src/__support/FPUtil/NormalFloat.h
index fa4da33b5b17fae..57a401d911fc666 100644
--- a/libc/src/__support/FPUtil/NormalFloat.h
+++ b/libc/src/__support/FPUtil/NormalFloat.h
@@ -96,7 +96,7 @@ template <typename T> struct NormalFloat {
     // Max exponent is of the form 0xFF...E. That is why -2 and not -1.
     constexpr int MAX_EXPONENT_VALUE = (1 << FPBits<T>::EXP_LEN) - 2;
     if (biased_exponent > MAX_EXPONENT_VALUE) {
-      return T(FPBits<T>::inf(sign));
+      return FPBits<T>::inf(sign).get_val();
     }
 
     FPBits<T> result(T(0.0));
@@ -129,15 +129,15 @@ template <typename T> struct NormalFloat {
         // the overflow into the exponent.
         if (new_mantissa == ONE)
           result.set_biased_exponent(1);
-        return T(result);
+        return result.get_val();
       } else {
-        return T(result);
+        return result.get_val();
       }
     }
 
     result.set_biased_exponent(exponent + FPBits<T>::EXP_BIAS);
     result.set_mantissa(mantissa);
-    return T(result);
+    return result.get_val();
   }
 
 private:
@@ -250,16 +250,16 @@ template <> LIBC_INLINE NormalFloat<long double>::operator long double() const {
       } else {
         result.set_implicit_bit(0);
       }
-      return static_cast<long double>(result);
+      return result.get_val();
     } else {
-      return static_cast<long double>(result);
+      return result.get_val();
     }
   }
 
   result.set_biased_exponent(biased_exponent);
   result.set_mantissa(mantissa);
   result.set_implicit_bit(1);
-  return static_cast<long double>(result);
+  return result.get_val();
 }
 #endif // LIBC_LONG_DOUBLE_IS_X86_FLOAT80
 
diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h
index 5c36463ea50213e..f03af9246337ffd 100644
--- a/libc/src/__support/FPUtil/generic/FMA.h
+++ b/libc/src/__support/FPUtil/generic/FMA.h
@@ -58,8 +58,8 @@ template <> LIBC_INLINE float fma<float>(float x, float y, float z) {
     // correct (when it matters).
     fputil::FPBits<double> t(
         (bit_prod.get_biased_exponent() >= bitz.get_biased_exponent())
-            ? ((double(bit_sum) - double(bit_prod)) - double(bitz))
-            : ((double(bit_sum) - double(bitz)) - double(bit_prod)));
+            ? ((bit_sum.get_val() - bit_prod.get_val()) - bitz.get_val())
+            : ((bit_sum.get_val() - bitz.get_val()) - bit_prod.get_val()));
 
     // Update sticky bits if t != 0.0 and the least (52 - 23 - 1 = 28) bits are
     // zero.
@@ -72,7 +72,7 @@ template <> LIBC_INLINE float fma<float>(float x, float y, float z) {
     }
   }
 
-  return static_cast<float>(static_cast<double>(bit_sum));
+  return static_cast<float>(bit_sum.get_val());
 }
 
 namespace internal {
@@ -257,7 +257,7 @@ template <> LIBC_INLINE double fma<double>(double x, double y, double z) {
         (round_mode == FE_DOWNWARD && prod_sign.is_pos())) {
       return FPBits::max_normal(prod_sign).get_val();
     }
-    return static_cast<double>(FPBits::inf(prod_sign));
+    return FPBits::inf(prod_sign).get_val();
   }
 
   // Remove hidden bit and append the exponent field and sign bit.
diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h
index 9655c993bee28f4..7ecb6c3e02fde3b 100644
--- a/libc/src/__support/str_to_float.h
+++ b/libc/src/__support/str_to_float.h
@@ -568,11 +568,11 @@ clinger_fast_path(ExpandedFloat<T> init_num,
                              ClingerConsts<T>::POWERS_OF_TEN_ARRAY[exp10]);
 
     // If the results are equal, then we don't need to use the rounding mode.
-    if (T(result) != -T(negative_result)) {
+    if (result.get_val() != -negative_result.get_val()) {
       FPBits lower_result;
       FPBits higher_result;
 
-      if (T(result) < -T(negative_result)) {
+      if (result.get_val() < -negative_result.get_val()) {
         lower_result = result;
         higher_result = negative_result;
       } else {
@@ -1194,7 +1194,7 @@ LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) {
   // special 80 bit long doubles. Otherwise it should be inlined out.
   set_implicit_bit<T>(result);
 
-  return {T(result), index, error};
+  return {result.get_val(), index, error};
 }
 
 template <class T> LIBC_INLINE StrToNumResult<T> strtonan(const char *arg) {
@@ -1216,7 +1216,7 @@ template <class T> LIBC_INLINE StrToNumResult<T> strtonan(const char *arg) {
   }
 
   result = FPBits::build_quiet_nan(fputil::Sign::POS, nan_mantissa);
-  return {T(result), 0, error};
+  return {result.get_val(), 0, error};
 }
 
 } // namespace internal
diff --git a/libc/src/math/generic/exp.cpp b/libc/src/math/generic/exp.cpp
index 49ea1699bb20934..f23170f8ed42590 100644
--- a/libc/src/math/generic/exp.cpp
+++ b/libc/src/math/generic/exp.cpp
@@ -222,7 +222,7 @@ double set_exceptional(double x) {
     fputil::raise_except_if_required(FE_OVERFLOW);
   }
   // x is +inf or nan
-  return x + static_cast<double>(FPBits::inf());
+  return x + FPBits::inf().get_val();
 }
 
 } // namespace
diff --git a/libc/src/math/generic/exp10.cpp b/libc/src/math/generic/exp10.cpp
index f1da03cba0b30bb..6b40f5561845d88 100644
--- a/libc/src/math/generic/exp10.cpp
+++ b/libc/src/math/generic/exp10.cpp
@@ -268,7 +268,7 @@ double set_exceptional(double x) {
     fputil::raise_except_if_required(FE_OVERFLOW);
   }
   // x is +inf or nan
-  return x + static_cast<double>(FPBits::inf());
+  return x + FPBits::inf().get_val();
 }
 
 } // namespace
diff --git a/libc/src/math/generic/exp2.cpp b/libc/src/math/generic/exp2.cpp
index 508bff9bd9fc9cf..01e66d1ae00f70f 100644
--- a/libc/src/math/generic/exp2.cpp
+++ b/libc/src/math/generic/exp2.cpp
@@ -243,7 +243,7 @@ double set_exceptional(double x) {
     fputil::raise_except_if_required(FE_OVERFLOW);
   }
   // x is +inf or nan
-  return x + static_cast<double>(FPBits::inf());
+  return x + FPBits::inf().get_val();
 }
 
 } // namespace
diff --git a/libc/src/math/generic/expf.cpp b/libc/src/math/generic/expf.cpp
index f3ce8400d0a41e9..c7ab974850a821a 100644
--- a/libc/src/math/generic/expf.cpp
+++ b/libc/src/math/generic/expf.cpp
@@ -67,7 +67,7 @@ LLVM_LIBC_FUNCTION(float, expf, (float x)) {
         fputil::raise_except_if_required(FE_OVERFLOW);
       }
       // x is +inf or nan
-      return x + static_cast<float>(FPBits::inf());
+      return x + FPBits::inf().get_val();
     }
   }
   // For -104 < x < 89, to compute exp(x), we perform the following range
diff --git a/libc/src/math/generic/hypotf.cpp b/libc/src/math/generic/hypotf.cpp
index 93dd4feb36bee65..9a0805e390eb37f 100644
--- a/libc/src/math/generic/hypotf.cpp
+++ b/libc/src/math/generic/hypotf.cpp
@@ -46,7 +46,7 @@ LLVM_LIBC_FUNCTION(float, hypotf, (float x, float y)) {
 
   if (!DoubleBits(sum_sq).is_inf_or_nan()) {
     // Correct rounding.
-    double r_sq = static_cast<double>(result) * static_cast<double>(result);
+    double r_sq = result.get_val() * result.get_val();
     double diff = sum_sq - r_sq;
     constexpr uint64_t mask = 0x0000'0000'3FFF'FFFFULL;
     uint64_t lrs = result.uintval() & mask;
@@ -60,14 +60,14 @@ LLVM_LIBC_FUNCTION(float, hypotf, (float x, float y)) {
     FPBits bits_x(x), bits_y(y);
     if (bits_x.is_inf_or_nan() || bits_y.is_inf_or_nan()) {
       if (bits_x.is_inf() || bits_y.is_inf())
-        return static_cast<float>(FPBits::inf());
+        return FPBits::inf().get_val();
       if (bits_x.is_nan())
         return x;
       return y;
     }
   }
 
-  return static_cast<float>(static_cast<double>(result));
+  return result.get_val();
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/log10f.cpp b/libc/src/math/generic/log10f.cpp
index f87e34ec5fb385f..ac2e3b9cf925a8b 100644
--- a/libc/src/math/generic/log10f.cpp
+++ b/libc/src/math/generic/log10f.cpp
@@ -191,7 +191,7 @@ LLVM_LIBC_FUNCTION(float, log10f, (float x)) {
   // Set bits to 1.m
   xbits.set_biased_exponent(0x7F);
 
-  float u = static_cast<float>(xbits);
+  float u = xbits.get_val();
   double v;
 #ifdef LIBC_TARGET_CPU_HAS_FMA
   v = static_cast<double>(fputil::multiply_add(u, R[index], -1.0f)); // Exact.
diff --git a/libc/src/math/generic/log1pf.cpp b/libc/src/math/generic/log1pf.cpp
index bc472caf54f89c6..8de4a2067f9d322 100644
--- a/libc/src/math/generic/log1pf.cpp
+++ b/libc/src/math/generic/log1pf.cpp
@@ -66,7 +66,7 @@ LIBC_INLINE float log(double x) {
   // Clear the lowest 45 bits.
   f.bits &= ~0x0000'1FFF'FFFF'FFFFULL;
 
-  double d = static_cast<double>(xbits) - static_cast<double>(f);
+  double d = xbits.get_val() - f.get_val();
   d *= ONE_OVER_F[f_index];
 
   double extra_factor = fputil::multiply_add(m, LOG_2, LOG_F[f_index]);
@@ -106,7 +106,7 @@ LLVM_LIBC_FUNCTION(float, log1pf, (float x)) {
     case 0xbf800000U: // x = -1.0
       fputil::set_errno_if_required(ERANGE);
       fputil::raise_except_if_required(FE_DIVBYZERO);
-      return static_cast<float>(fputil::FPBits<float>::inf(fputil::Sign::NEG));
+      return FPBits::inf(fputil::Sign::NEG).get_val();
 #ifndef LIBC_TARGET_CPU_HAS_FMA
     case 0x4cc1c80bU: // x = 0x1.839016p+26f
       return fputil::round_result_slightly_down(0x1.26fc04p+4f);
diff --git a/libc/src/math/generic/log2f.cpp b/libc/src/math/generic/log2f.cpp
index 7eaa5d53ccedd33..e3417552ad35a58 100644
--- a/libc/src/math/generic/log2f.cpp
+++ b/libc/src/math/generic/log2f.cpp
@@ -94,7 +94,7 @@ LLVM_LIBC_FUNCTION(float, log2f, (float x)) {
   // Set bits to 1.m
   xbits.set_biased_exponent(0x7F);
 
-  float u = static_cast<float>(xbits);
+  float u = xbits.get_val();
   double v;
 #ifdef LIBC_TARGET_CPU_HAS_FMA
   v = static_cast<double>(fputil::multiply_add(u, R[index], -1.0f)); // Exact.
diff --git a/libc/src/math/generic/logf.cpp b/libc/src/math/generic/logf.cpp
index 88f7ea01b2f19a5..4ad5a4e9b6ad8b4 100644
--- a/libc/src/math/generic/logf.cpp
+++ b/libc/src/math/generic/logf.cpp
@@ -85,7 +85,7 @@ LLVM_LIBC_FUNCTION(float, logf, (float x)) {
         // Return -inf and raise FE_DIVBYZERO
         fputil::set_errno_if_required(ERANGE);
         fputil::raise_except_if_required(FE_DIVBYZERO);
-        return static_cast<float>(FPBits::inf(fputil::Sign::NEG));
+        return FPBits::inf(Sign::NEG).get_val();
       }
       // Normalize denormal inputs.
       xbits = FPBits(xbits.get_val() * 0x1.0p23f);
@@ -149,7 +149,7 @@ LLVM_LIBC_FUNCTION(float, logf, (float x)) {
   // Set bits to 1.m
   xbits.set_biased_exponent(0x7F);
 
-  float u = static_cast<float>(xbits);
+  float u = xbits.get_val();
   double v;
 #ifdef LIBC_TARGET_CPU_HAS_FMA
   v = static_cast<double>(fputil::multiply_add(u, R[index], -1.0f)); // Exact.
diff --git a/libc/src/math/generic/range_reduction_fma.h b/libc/src/math/generic/range_reduction_fma.h
index 13a7360b4233289..d2ca5d348aadd5b 100644
--- a/libc/src/math/generic/range_reduction_fma.h
+++ b/libc/src/math/generic/range_reduction_fma.h
@@ -52,7 +52,7 @@ LIBC_INLINE int64_t large_range_reduction(double x, int x_exp, double &y) {
     // least 2^6.
     fputil::FPBits<double> prod_hi(x * THIRTYTWO_OVER_PI[0]);
     prod_hi.bits &= (x_exp < 55) ? (~0xfffULL) : (~0ULL); // |x| < 2^55
-    double k_hi = fputil::nearest_integer(static_cast<double>(prod_hi));
+    double k_hi = fputil::nearest_integer(prod_hi.get_val());
     double truncated_prod = fputil::fma(x, THIRTYTWO_OVER_PI[0], -k_hi);
     double prod_lo = fputil::fma(x, THIRTYTWO_OVER_PI[1], truncated_prod);
     double k_lo = fputil::nearest_integer(prod_lo);
@@ -71,7 +71,7 @@ LIBC_INLINE int64_t large_range_reduction(double x, int x_exp, double &y) {
   // least 64.
   fputil::FPBits<double> prod_hi(x * THIRTYTWO_OVER_PI[1]);
   prod_hi.bits &= (x_exp < 110) ? (~0xfffULL) : (~0ULL); // |x| < 2^110
-  double k_hi = fputil::nearest_integer(static_cast<double>(prod_hi));
+  double k_hi = fputil::nearest_integer(prod_hi.get_val());
   double truncated_prod = fputil::fma(x, THIRTYTWO_OVER_PI[1], -k_hi);
   double prod_lo = fputil::fma(x, THIRTYTWO_OVER_PI[2], truncated_prod);
   double k_lo = fputil::nearest_integer(prod_lo);
diff --git a/libc/src/stdio/printf_core/float_dec_converter.h b/libc/src/stdio/printf_core/float_dec_converter.h
index 6171d1d5946e6a2..b54526d3710860d 100644
--- a/libc/src/stdio/printf_core/float_dec_converter.h
+++ b/libc/src/stdio/printf_core/float_dec_converter.h
@@ -498,7 +498,7 @@ LIBC_INLINE int convert_float_decimal_typed(Writer *writer,
 
   PaddingWriter padding_writer(to_conv, sign_char);
   FloatWriter float_writer(writer, has_decimal_point, padding_writer);
-  FloatToString<T> float_converter(static_cast<T>(float_bits));
+  FloatToString<T> float_converter(float_bits.get_val());
 
   const size_t positive_blocks = float_converter.get_positive_blocks();
 
@@ -608,7 +608,7 @@ LIBC_INLINE int convert_float_dec_exp_typed(Writer *writer,
 
   PaddingWriter padding_writer(to_conv, sign_char);
   FloatWriter float_writer(writer, has_decimal_point, padding_writer);
-  FloatToString<T> float_converter(static_cast<T>(float_bits));
+  FloatToString<T> float_converter(float_bits.get_val());
 
   size_t digits_written = 0;
   int final_exponent = 0;
@@ -767,7 +767,7 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer *writer,
   // it has style E, so here we calculate the precision we'll use in that case.
   const unsigned int exp_precision = init_precision - 1;
 
-  FloatToString<T> float_converter(static_cast<T>(float_bits));
+  FloatToString<T> float_converter(float_bits.get_val());
 
   // Here we would subtract 1 to account for the fact that block 0 counts as a
   // positive block, but the loop below accounts for this by starting with
diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index ad2fc0439fd7904..3cdaffcfdcedf1d 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -66,16 +66,16 @@ template <typename T> struct FPTest : public Test {
   using Sign = LIBC_NAMESPACE::fputil::Sign;
   static constexpr StorageType STORAGE_MAX =
       LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::max();
-  static constexpr T zero = T(FPBits::zero(Sign::POS));
-  static constexpr T neg_zero = T(FPBits::zero(Sign::NEG));
-  static constexpr T aNaN = T(FPBits::build_quiet_nan());
-  static constexpr T sNaN = T(FPBits::build_nan(Sign::POS, 1));
-  static constexpr T inf = T(FPBits::inf(Sign::POS));
-  static constexpr T neg_inf = T(FPBits::inf(Sign::NEG));
-  static constexpr T min_normal = T(FPBits::min_normal());
-  static constexpr T max_normal = T(FPBits::max_normal());
-  static constexpr T min_denormal = T(FPBits::min_subnormal());
-  static constexpr T max_denormal = T(FPBits::max_subnormal());
+  static constexpr T zero = FPBits::zero(Sign::POS).get_val();
+  static constexpr T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  static constexpr T aNaN = FPBits::build_quiet_nan().get_val();
+  static constexpr T sNaN = FPBits::build_nan(Sign::POS, 1).get_val();
+  static constexpr T inf = FPBits::inf(Sign::POS).get_val();
+  static constexpr T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  static constexpr T min_normal = FPBits::min_normal().get_val();
+  static constexpr T max_normal = FPBits::max_normal().get_val();
+  static constexpr T min_denormal = FPBits::min_subnormal().get_val();
+  static constexpr T max_denormal = FPBits::max_subnormal().get_val();
 
   static constexpr int N_ROUNDING_MODES = 4;
   static constexpr fputil::testing::RoundingMode ROUNDING_MODES[4] = {
@@ -95,16 +95,16 @@ template <typename T> struct FPTest : public Test {
   using Sign = LIBC_NAMESPACE::fputil::Sign;                                   \
   static constexpr StorageType STORAGE_MAX =                                   \
       LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::max();                 \
-  const T zero = T(FPBits::zero(Sign::POS));                                   \
-  const T neg_zero = T(FPBits::zero(Sign::NEG));                               \
-  const T aNaN = T(FPBits::build_quiet_nan());                                 \
-  const T sNaN = T(FPBits::build_nan(Sign::POS, 1));                           \
-  const T inf = T(FPBits::inf(Sign::POS));                                     \
-  const T neg_inf = T(FPBits::inf(Sign::NEG));                                 \
-  const T min_normal = T(FPBits::min_normal());                                \
-  const T max_normal = T(FPBits::max_normal());                                \
-  const T min_denormal = T(FPBits::min_subnormal());                           \
-  const T max_denormal = T(FPBits::max_subnormal());
+  const T zero = FPBits::zero(Sign::POS).get_val();                            \
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();                        \
+  const T aNaN = FPBits::build_quiet_nan().get_val();              \
+  const T sNaN = FPBits::build_nan(Sign::POS, 1).get_val();                    \
+  const T inf = FPBits::inf(Sign::POS).get_val();                              \
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();                          \
+  const T min_normal = FPBits::min_normal().get_val();                         \
+  const T max_normal = FPBits::max_normal().get_val();                         \
+  const T min_denormal = FPBits::min_subnormal().get_val();                    \
+  const T max_denormal = FPBits::max_subnormal().get_val();
 
 #define EXPECT_FP_EQ(expected, actual)                                         \
   EXPECT_THAT(actual, LIBC_NAMESPACE::testing::getMatcher<                     \
diff --git a/libc/test/src/math/CeilTest.h b/libc/test/src/math/CeilTest.h
index 67b33cb14110bcc..5ea4f349d008b3d 100644
--- a/libc/test/src/math/CeilTest.h
+++ b/libc/test/src/math/CeilTest.h
@@ -67,7 +67,7 @@ template <typename T> class CeilTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'000;
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-      T x = T(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x))
         continue;
 
diff --git a/libc/test/src/math/CopySignTest.h b/libc/test/src/math/CopySignTest.h
index c916416a2e5b916..8b81e8d7de25231 100644
--- a/libc/test/src/math/CopySignTest.h
+++ b/libc/test/src/math/CopySignTest.h
@@ -37,7 +37,7 @@ class CopySignTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'000;
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-      T x = T(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x))
         continue;
 
diff --git a/libc/test/src/math/FAbsTest.h b/libc/test/src/math/FAbsTest.h
index b2b146167e62529..bf3052afc816fb4 100644
--- a/libc/test/src/math/FAbsTest.h
+++ b/libc/test/src/math/FAbsTest.h
@@ -35,7 +35,7 @@ template <typename T> class FAbsTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'000;
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-      T x = T(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x))
         continue;
       ASSERT_MPFR_MATCH(mpfr::Operation::Abs, x, func(x), 0.0);
diff --git a/libc/test/src/math/FDimTest.h b/libc/test/src/math/FDimTest.h
index 46df2b40e64bd1b..31df2f5607c2662 100644
--- a/libc/test/src/math/FDimTest.h
+++ b/libc/test/src/math/FDimTest.h
@@ -20,11 +20,11 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
   void test_na_n_arg(FuncPtr func) {
     EXPECT_FP_EQ(nan, func(nan, inf));
@@ -66,7 +66,7 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
          ++i, v += STEP, w -= STEP) {
-      T x = T(FPBits(v)), y = T(FPBits(w));
+      T x = FPBits(v).get_val(), y = FPBits(w).get_val();
       if (isnan(x) || isinf(x))
         continue;
       if (isnan(y) || isinf(y))
diff --git a/libc/test/src/math/FMaxTest.h b/libc/test/src/math/FMaxTest.h
index 1a1d2a77268d1cb..edc46ae5bb0fe32 100644
--- a/libc/test/src/math/FMaxTest.h
+++ b/libc/test/src/math/FMaxTest.h
@@ -59,7 +59,7 @@ template <typename T> class FMaxTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
          ++i, v += STEP, w -= STEP) {
-      T x = T(FPBits(v)), y = T(FPBits(w));
+      T x = FPBits(v).get_val(), y = FPBits(w).get_val();
       if (isnan(x) || isinf(x))
         continue;
       if (isnan(y) || isinf(y))
diff --git a/libc/test/src/math/FMinTest.h b/libc/test/src/math/FMinTest.h
index 742bb5cdd1021b9..5ff583604ebc521 100644
--- a/libc/test/src/math/FMinTest.h
+++ b/libc/test/src/math/FMinTest.h
@@ -59,7 +59,7 @@ template <typename T> class FMinTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
          ++i, v += STEP, w -= STEP) {
-      T x = T(FPBits(v)), y = T(FPBits(w));
+      T x = FPBits(v).get_val(), y = FPBits(w).get_val();
       if (isnan(x) || isinf(x))
         continue;
       if (isnan(y) || isinf(y))
diff --git a/libc/test/src/math/FloorTest.h b/libc/test/src/math/FloorTest.h
index c1b05c5d1308346..5e459ebd4928919 100644
--- a/libc/test/src/math/FloorTest.h
+++ b/libc/test/src/math/FloorTest.h
@@ -67,7 +67,7 @@ template <typename T> class FloorTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'000;
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-      T x = T(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x))
         continue;
 
diff --git a/libc/test/src/math/FmaTest.h b/libc/test/src/math/FmaTest.h
index 8cc340e9260ff2c..dd6832e129144af 100644
--- a/libc/test/src/math/FmaTest.h
+++ b/libc/test/src/math/FmaTest.h
@@ -25,14 +25,14 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T min_subnormal = T(FPBits::min_subnormal(Sign::POS));
-  const T min_normal = T(FPBits::min_normal(Sign::POS));
-  const T max_normal = T(FPBits::max_normal(Sign::POS));
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T min_subnormal = FPBits::min_subnormal(Sign::POS).get_val();
+  const T min_normal = FPBits::min_normal(Sign::POS).get_val();
+  const T max_normal = FPBits::max_normal(Sign::POS).get_val();
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
   static constexpr StorageType MAX_NORMAL = FPBits::max_normal().uintval();
   static constexpr StorageType MIN_NORMAL = FPBits::min_normal().uintval();
@@ -63,9 +63,9 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test {
 
     // Test underflow rounding up.
     EXPECT_FP_EQ(func(T(0.5), min_subnormal, min_subnormal),
-                 T(FPBits(StorageType(2))));
+                 FPBits(StorageType(2)).get_val());
     // Test underflow rounding down.
-    T v = T(FPBits(MIN_NORMAL + StorageType(1)));
+    T v = FPBits(MIN_NORMAL + StorageType(1)).get_val();
     EXPECT_FP_EQ(func(T(1) / T(MIN_NORMAL << 1), v, min_normal), v);
     // Test overflow.
     T z = max_normal;
@@ -80,8 +80,8 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType STEP = (MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT;
     for (StorageType v = MIN_SUBNORMAL, w = MAX_SUBNORMAL;
          v <= MAX_SUBNORMAL && w >= MIN_SUBNORMAL; v += STEP, w -= STEP) {
-      T x = T(FPBits(get_random_bit_pattern())), y = T(FPBits(v)),
-        z = T(FPBits(w));
+      T x = FPBits(get_random_bit_pattern()).get_val(), y = FPBits(v).get_val(),
+        z = FPBits(w).get_val();
       mpfr::TernaryInput<T> input{x, y, z};
       ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fma, input, func(x, y, z),
                                      0.5);
@@ -93,8 +93,8 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType STEP = (MAX_NORMAL - MIN_NORMAL) / COUNT;
     for (StorageType v = MIN_NORMAL, w = MAX_NORMAL;
          v <= MAX_NORMAL && w >= MIN_NORMAL; v += STEP, w -= STEP) {
-      T x = T(FPBits(v)), y = T(FPBits(w)),
-        z = T(FPBits(get_random_bit_pattern()));
+      T x = FPBits(v).get_val(), y = FPBits(w).get_val(),
+        z = FPBits(get_random_bit_pattern()).get_val();
       mpfr::TernaryInput<T> input{x, y, z};
       ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fma, input, func(x, y, z),
                                      0.5);
diff --git a/libc/test/src/math/FrexpTest.h b/libc/test/src/math/FrexpTest.h
index 20ddce807da4575..f3a64ce4aac31fb 100644
--- a/libc/test/src/math/FrexpTest.h
+++ b/libc/test/src/math/FrexpTest.h
@@ -96,7 +96,7 @@ template <typename T> class FrexpTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'000;
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-      T x = static_cast<T>(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x) || x == 0.0l)
         continue;
 
diff --git a/libc/test/src/math/HypotTest.h b/libc/test/src/math/HypotTest.h
index 2990072fd5c668c..9f2d148be6b91ce 100644
--- a/libc/test/src/math/HypotTest.h
+++ b/libc/test/src/math/HypotTest.h
@@ -25,15 +25,15 @@ class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
   using StorageType = typename FPBits::StorageType;
-  const T nan = T(FPBits::build_quiet_nan());
-  const T inf = T(FPBits::inf());
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero());
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T max_normal = T(FPBits::max_normal());
-  const T min_normal = T(FPBits::min_normal());
-  const T max_subnormal = T(FPBits::max_subnormal());
-  const T min_subnormal = T(FPBits::min_subnormal());
+  const T nan = FPBits::build_quiet_nan().get_val();
+  const T inf = FPBits::inf().get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero().get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T max_normal = FPBits::max_normal().get_val();
+  const T min_normal = FPBits::min_normal().get_val();
+  const T max_subnormal = FPBits::max_subnormal().get_val();
+  const T min_subnormal = FPBits::min_subnormal().get_val();
 
   static constexpr StorageType MAX_NORMAL = FPBits::max_normal().uintval();
   static constexpr StorageType MIN_NORMAL = FPBits::min_normal().uintval();
@@ -74,7 +74,7 @@ class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test {
       for (int signs = 0; signs < 4; ++signs) {
         for (StorageType v = MIN_SUBNORMAL, w = max_value;
              v <= max_value && w >= MIN_SUBNORMAL; v += step, w -= step) {
-          T x = T(FPBits(v)), y = T(FPBits(w));
+          T x = FPBits(v).get_val(), y = FPBits(w).get_val();
           if (signs % 2 == 1) {
             x = -x;
           }
@@ -96,7 +96,7 @@ class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test {
     for (int signs = 0; signs < 4; ++signs) {
       for (StorageType v = MIN_NORMAL, w = MAX_NORMAL;
            v <= MAX_NORMAL && w >= MIN_NORMAL; v += STEP, w -= STEP) {
-        T x = T(FPBits(v)), y = T(FPBits(w));
+        T x = FPBits(v).get_val(), y = FPBits(w).get_val();
         if (signs % 2 == 1) {
           x = -x;
         }
diff --git a/libc/test/src/math/ILogbTest.h b/libc/test/src/math/ILogbTest.h
index fe28fab9d777c99..fb8d77093eba3c9 100644
--- a/libc/test/src/math/ILogbTest.h
+++ b/libc/test/src/math/ILogbTest.h
@@ -26,11 +26,11 @@ class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
   void test_special_numbers(typename ILogbFunc<T>::Func func) {
     using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
     using Sign = LIBC_NAMESPACE::fputil::Sign;
-    EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero(Sign::POS))));
-    EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero(Sign::NEG))));
-    EXPECT_EQ(FP_ILOGBNAN, func(T(FPBits::build_quiet_nan())));
-    EXPECT_EQ(INT_MAX, func(T(FPBits::inf(Sign::POS))));
-    EXPECT_EQ(INT_MAX, func(T(FPBits::inf(Sign::NEG))));
+    EXPECT_EQ(FP_ILOGB0, func(FPBits::zero(Sign::POS).get_val()));
+    EXPECT_EQ(FP_ILOGB0, func(FPBits::zero(Sign::NEG).get_val()));
+    EXPECT_EQ(FP_ILOGBNAN, func(FPBits::build_quiet_nan().get_val()));
+    EXPECT_EQ(INT_MAX, func(FPBits::inf(Sign::POS).get_val()));
+    EXPECT_EQ(INT_MAX, func(FPBits::inf(Sign::NEG).get_val()));
   }
 
   template <typename T>
@@ -81,7 +81,7 @@ class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 10'001;
     constexpr StorageType STEP = (MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT;
     for (StorageType v = MIN_SUBNORMAL; v <= MAX_SUBNORMAL; v += STEP) {
-      T x = T(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x) || x == 0.0)
         continue;
 
@@ -100,7 +100,7 @@ class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 10'001;
     constexpr StorageType STEP = (MAX_NORMAL - MIN_NORMAL) / COUNT;
     for (StorageType v = MIN_NORMAL; v <= MAX_NORMAL; v += STEP) {
-      T x = T(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x) || x == 0.0)
         continue;
 
diff --git a/libc/test/src/math/LdExpTest.h b/libc/test/src/math/LdExpTest.h
index 08a14a90c122636..1d581f2c0a02fcb 100644
--- a/libc/test/src/math/LdExpTest.h
+++ b/libc/test/src/math/LdExpTest.h
@@ -25,11 +25,11 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
   // A normalized mantissa to be used with tests.
   static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234;
diff --git a/libc/test/src/math/LogbTest.h b/libc/test/src/math/LogbTest.h
index 196da5e96b076f4..d64c5c44e4281a5 100644
--- a/libc/test/src/math/LogbTest.h
+++ b/libc/test/src/math/LogbTest.h
@@ -75,7 +75,7 @@ template <typename T> class LogbTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'000;
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-      T x = static_cast<T>(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x) || x == 0.0l)
         continue;
 
diff --git a/libc/test/src/math/ModfTest.h b/libc/test/src/math/ModfTest.h
index f5196a74fa7425c..a7e5e8810611b1b 100644
--- a/libc/test/src/math/ModfTest.h
+++ b/libc/test/src/math/ModfTest.h
@@ -87,7 +87,7 @@ template <typename T> class ModfTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'000;
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-      T x = T(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x) || x == T(0.0))
         continue;
 
diff --git a/libc/test/src/math/NextAfterTest.h b/libc/test/src/math/NextAfterTest.h
index f9ae4a4ec5c021a..2bbc3891205a58d 100644
--- a/libc/test/src/math/NextAfterTest.h
+++ b/libc/test/src/math/NextAfterTest.h
@@ -23,11 +23,11 @@ class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
   const StorageType min_subnormal = FPBits::min_subnormal().uintval();
   const StorageType max_subnormal = FPBits::max_subnormal().uintval();
diff --git a/libc/test/src/math/RIntTest.h b/libc/test/src/math/RIntTest.h
index 3af7b6fe6f6d4fa..c6693981df5ebef 100644
--- a/libc/test/src/math/RIntTest.h
+++ b/libc/test/src/math/RIntTest.h
@@ -34,11 +34,11 @@ class RIntTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
   static constexpr StorageType MIN_SUBNORMAL =
       FPBits::min_subnormal().uintval();
@@ -104,7 +104,7 @@ class RIntTestTemplate : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'001;
     constexpr StorageType STEP = (MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT;
     for (StorageType i = MIN_SUBNORMAL; i <= MAX_SUBNORMAL; i += STEP) {
-      T x = T(FPBits(i));
+      T x = FPBits(i).get_val();
       for (int mode : ROUNDING_MODES) {
         LIBC_NAMESPACE::fputil::set_round(mode);
         mpfr::RoundingMode mpfr_mode = to_mpfr_rounding_mode(mode);
@@ -117,7 +117,7 @@ class RIntTestTemplate : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'001;
     constexpr StorageType STEP = (MAX_NORMAL - MIN_NORMAL) / COUNT;
     for (StorageType i = MIN_NORMAL; i <= MAX_NORMAL; i += STEP) {
-      T x = T(FPBits(i));
+      T x = FPBits(i).get_val();
       // In normal range on x86 platforms, the long double implicit 1 bit can be
       // zero making the numbers NaN. We will skip them.
       if (isnan(x)) {
diff --git a/libc/test/src/math/RemQuoTest.h b/libc/test/src/math/RemQuoTest.h
index bbc266764c1c211..16a439a5fea6dd2 100644
--- a/libc/test/src/math/RemQuoTest.h
+++ b/libc/test/src/math/RemQuoTest.h
@@ -24,11 +24,11 @@ class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
   static constexpr StorageType MIN_SUBNORMAL =
       FPBits::min_subnormal().uintval();
@@ -107,7 +107,7 @@ class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType STEP = (MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT;
     for (StorageType v = MIN_SUBNORMAL, w = MAX_SUBNORMAL;
          v <= MAX_SUBNORMAL && w >= MIN_SUBNORMAL; v += STEP, w -= STEP) {
-      T x = T(FPBits(v)), y = T(FPBits(w));
+      T x = FPBits(v).get_val(), y = FPBits(w).get_val();
       mpfr::BinaryOutput<T> result;
       mpfr::BinaryInput<T> input{x, y};
       result.f = func(x, y, &result.i);
@@ -120,7 +120,7 @@ class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType STEP = (MAX_NORMAL - MIN_NORMAL) / COUNT;
     for (StorageType v = MIN_NORMAL, w = MAX_NORMAL;
          v <= MAX_NORMAL && w >= MIN_NORMAL; v += STEP, w -= STEP) {
-      T x = T(FPBits(v)), y = T(FPBits(w));
+      T x = FPBits(v).get_val(), y = FPBits(w).get_val();
       mpfr::BinaryOutput<T> result;
       mpfr::BinaryInput<T> input{x, y};
       result.f = func(x, y, &result.i);
diff --git a/libc/test/src/math/RoundTest.h b/libc/test/src/math/RoundTest.h
index 3ec46159c65d952..4860464be9089d7 100644
--- a/libc/test/src/math/RoundTest.h
+++ b/libc/test/src/math/RoundTest.h
@@ -67,7 +67,7 @@ template <typename T> class RoundTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'000;
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-      T x = T(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x))
         continue;
 
diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h
index f75aaa348bd0068..a2a88c75a733f2a 100644
--- a/libc/test/src/math/RoundToIntegerTest.h
+++ b/libc/test/src/math/RoundToIntegerTest.h
@@ -33,11 +33,11 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const F zero = F(FPBits::zero());
-  const F neg_zero = F(FPBits::zero(Sign::NEG));
-  const F inf = F(FPBits::inf());
-  const F neg_inf = F(FPBits::inf(Sign::NEG));
-  const F nan = F(FPBits::build_quiet_nan());
+  const F zero = FPBits::zero().get_val();
+  const F neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const F inf = FPBits::inf().get_val();
+  const F neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const F nan = FPBits::build_quiet_nan().get_val();
 
   static constexpr StorageType MAX_NORMAL = FPBits::max_normal().uintval();
   static constexpr StorageType MIN_NORMAL = FPBits::min_normal().uintval();
@@ -139,7 +139,7 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
     bits.set_sign(Sign::NEG);
     bits.set_mantissa(0);
 
-    F x = F(bits);
+    F x = bits.get_val();
     long mpfr_result;
     bool erangeflag = mpfr::round_to_long(x, mpfr_result);
     ASSERT_FALSE(erangeflag);
@@ -203,7 +203,7 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
     bits.set_sign(Sign::NEG);
     bits.set_mantissa(FPBits::FRACTION_MASK);
 
-    F x = F(bits);
+    F x = bits.get_val();
     if (TestModes) {
       for (int m : ROUNDING_MODES) {
         LIBC_NAMESPACE::fputil::set_round(m);
@@ -225,7 +225,7 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 1'000'001;
     constexpr StorageType STEP = (MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT;
     for (StorageType i = MIN_SUBNORMAL; i <= MAX_SUBNORMAL; i += STEP) {
-      F x = F(FPBits(i));
+      F x = FPBits(i).get_val();
       if (x == F(0.0))
         continue;
       // All subnormal numbers should round to zero.
@@ -267,7 +267,7 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 1'000'001;
     constexpr StorageType STEP = (MAX_NORMAL - MIN_NORMAL) / COUNT;
     for (StorageType i = MIN_NORMAL; i <= MAX_NORMAL; i += STEP) {
-      F x = F(FPBits(i));
+      F x = FPBits(i).get_val();
       // In normal range on x86 platforms, the long double implicit 1 bit can be
       // zero making the numbers NaN. We will skip them.
       if (isnan(x)) {
diff --git a/libc/test/src/math/SqrtTest.h b/libc/test/src/math/SqrtTest.h
index d58c3ccfdd5a229..75eb411810f5ee9 100644
--- a/libc/test/src/math/SqrtTest.h
+++ b/libc/test/src/math/SqrtTest.h
@@ -41,7 +41,7 @@ template <typename T> class SqrtTest : public LIBC_NAMESPACE::testing::Test {
     for (StorageType mant = 1; mant < HIDDEN_BIT; mant <<= 1) {
       FPBits denormal(T(0.0));
       denormal.set_mantissa(mant);
-      T x = T(denormal);
+      T x = denormal.get_val();
       EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sqrt, x, func(x), 0.5);
     }
 
diff --git a/libc/test/src/math/TruncTest.h b/libc/test/src/math/TruncTest.h
index 2be40790258ef7a..0d99363526e8a50 100644
--- a/libc/test/src/math/TruncTest.h
+++ b/libc/test/src/math/TruncTest.h
@@ -67,7 +67,7 @@ template <typename T> class TruncTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'000;
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-      T x = T(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x))
         continue;
 
diff --git a/libc/test/src/math/acosf_test.cpp b/libc/test/src/math/acosf_test.cpp
index 409cf2bc891332f..81f697c315a2809 100644
--- a/libc/test/src/math/acosf_test.cpp
+++ b/libc/test/src/math/acosf_test.cpp
@@ -47,7 +47,7 @@ TEST_F(LlvmLibcAcosfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acos, x,
@@ -74,7 +74,7 @@ TEST_F(LlvmLibcAcosfTest, SpecificBitPatterns) {
   };
 
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acos, x,
                                    LIBC_NAMESPACE::acosf(x), 0.5);
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acos, -x,
diff --git a/libc/test/src/math/acoshf_test.cpp b/libc/test/src/math/acoshf_test.cpp
index fe8d76918d486b2..6d43105c83c28a1 100644
--- a/libc/test/src/math/acoshf_test.cpp
+++ b/libc/test/src/math/acoshf_test.cpp
@@ -44,7 +44,7 @@ TEST_F(LlvmLibcAcoshfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, x,
@@ -70,7 +70,7 @@ TEST_F(LlvmLibcAcoshfTest, SpecificBitPatterns) {
   };
 
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, x,
                                    LIBC_NAMESPACE::acoshf(x), 0.5);
   }
diff --git a/libc/test/src/math/asinf_test.cpp b/libc/test/src/math/asinf_test.cpp
index db9dd0d78404aad..77ac2bc216f77c6 100644
--- a/libc/test/src/math/asinf_test.cpp
+++ b/libc/test/src/math/asinf_test.cpp
@@ -45,7 +45,7 @@ TEST_F(LlvmLibcAsinfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Asin, x,
@@ -70,7 +70,7 @@ TEST_F(LlvmLibcAsinfTest, SpecificBitPatterns) {
   };
 
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Asin, x,
                                    LIBC_NAMESPACE::asinf(x), 0.5);
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Asin, -x,
diff --git a/libc/test/src/math/asinhf_test.cpp b/libc/test/src/math/asinhf_test.cpp
index 2afb5b3a9ff8d22..9b925bf254a93fd 100644
--- a/libc/test/src/math/asinhf_test.cpp
+++ b/libc/test/src/math/asinhf_test.cpp
@@ -44,7 +44,7 @@ TEST_F(LlvmLibcAsinhfTest, InFloatRange) {
   constexpr uint32_t COUNT = 1'001;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Asinh, x,
@@ -71,7 +71,7 @@ TEST_F(LlvmLibcAsinhfTest, SpecificBitPatterns) {
   };
 
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Asinh, x,
                                    LIBC_NAMESPACE::asinhf(x), 0.5);
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Asinh, -x,
diff --git a/libc/test/src/math/atanf_test.cpp b/libc/test/src/math/atanf_test.cpp
index 61d202e22bdc6f9..b5d30fbd5679e7d 100644
--- a/libc/test/src/math/atanf_test.cpp
+++ b/libc/test/src/math/atanf_test.cpp
@@ -43,7 +43,7 @@ TEST_F(LlvmLibcAtanfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   const uint32_t STEP = FPBits(inf).uintval() / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
                                    LIBC_NAMESPACE::atanf(x), 0.5);
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, -x,
@@ -56,7 +56,7 @@ TEST_F(LlvmLibcAtanfTest, SpecialValues) {
   uint32_t val_arr[] = {0x3d8d6b23U, 0x3feefcfbU, 0xbd8d6b23U,
                         0xbfeefcfbU, 0x7F800000U, 0xFF800000U};
   for (uint32_t v : val_arr) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Atan, x,
                                    LIBC_NAMESPACE::atanf(x), 0.5);
   }
diff --git a/libc/test/src/math/atanhf_test.cpp b/libc/test/src/math/atanhf_test.cpp
index fcc9f44dbea9323..0080a328fbea689 100644
--- a/libc/test/src/math/atanhf_test.cpp
+++ b/libc/test/src/math/atanhf_test.cpp
@@ -88,7 +88,7 @@ TEST_F(LlvmLibcAtanhfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   const uint32_t STEP = FPBits(1.0f).uintval() / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     ASSERT_MPFR_MATCH(mpfr::Operation::Atanh, x, LIBC_NAMESPACE::atanhf(x),
                       0.5);
     ASSERT_MPFR_MATCH(mpfr::Operation::Atanh, -x, LIBC_NAMESPACE::atanhf(-x),
@@ -98,12 +98,12 @@ TEST_F(LlvmLibcAtanhfTest, InFloatRange) {
 
 // For small values, atanh(x) is x.
 TEST_F(LlvmLibcAtanhfTest, SmallValues) {
-  float x = float(FPBits(uint32_t(0x17800000)));
+  float x = FPBits(uint32_t(0x17800000)).get_val();
   float result = LIBC_NAMESPACE::atanhf(x);
   EXPECT_MPFR_MATCH(mpfr::Operation::Atanh, x, result, 0.5);
   EXPECT_FP_EQ(x, result);
 
-  x = float(FPBits(uint32_t(0x00400000)));
+  x = FPBits(uint32_t(0x00400000)).get_val();
   result = LIBC_NAMESPACE::atanhf(x);
   EXPECT_MPFR_MATCH(mpfr::Operation::Atanh, x, result, 0.5);
   EXPECT_FP_EQ(x, result);
diff --git a/libc/test/src/math/cos_test.cpp b/libc/test/src/math/cos_test.cpp
index a4c332bc7fb52b9..1f55e9e9a149597 100644
--- a/libc/test/src/math/cos_test.cpp
+++ b/libc/test/src/math/cos_test.cpp
@@ -22,7 +22,7 @@ TEST_F(LlvmLibcCosTest, Range) {
   constexpr StorageType COUNT = 100'000;
   constexpr StorageType STEP = STORAGE_MAX / COUNT;
   for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    double x = double(FPBits(v));
+    double x = FPBits(v).get_val();
     // TODO: Expand the range of testing after range reduction is implemented.
     if (isnan(x) || isinf(x) || x > _2pi || x < -_2pi)
       continue;
diff --git a/libc/test/src/math/cosf_test.cpp b/libc/test/src/math/cosf_test.cpp
index 5a16520439af07e..9a988d76c598f43 100644
--- a/libc/test/src/math/cosf_test.cpp
+++ b/libc/test/src/math/cosf_test.cpp
@@ -46,7 +46,7 @@ TEST_F(LlvmLibcCosfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Cos, x,
@@ -102,7 +102,7 @@ TEST_F(LlvmLibcCosfTest, SpecificBitPatterns) {
   };
 
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Cos, x,
                                    LIBC_NAMESPACE::cosf(x), 0.5);
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Cos, -x,
@@ -114,7 +114,7 @@ TEST_F(LlvmLibcCosfTest, SpecificBitPatterns) {
 // returns values furthest beyond its nominal upper bound of pi/4.
 TEST_F(LlvmLibcCosfTest, SDCOMP_26094) {
   for (uint32_t v : SDCOMP26094_VALUES) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     ASSERT_MPFR_MATCH(mpfr::Operation::Cos, x, LIBC_NAMESPACE::cosf(x), 0.5);
   }
 }
diff --git a/libc/test/src/math/coshf_test.cpp b/libc/test/src/math/coshf_test.cpp
index 797cfec566ac821..843ecb8925ad383 100644
--- a/libc/test/src/math/coshf_test.cpp
+++ b/libc/test/src/math/coshf_test.cpp
@@ -44,15 +44,15 @@ TEST_F(LlvmLibcCoshfTest, SpecialNumbers) {
 TEST_F(LlvmLibcCoshfTest, Overflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::coshf(float(FPBits(0x7f7fffffU))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::coshf(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::coshf(float(FPBits(0x42cffff8U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::coshf(FPBits(0x42cffff8U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::coshf(float(FPBits(0x42d00008U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::coshf(FPBits(0x42d00008U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 }
 
@@ -60,7 +60,7 @@ TEST_F(LlvmLibcCoshfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     ASSERT_MPFR_MATCH(mpfr::Operation::Cosh, x, LIBC_NAMESPACE::coshf(x), 0.5);
@@ -68,12 +68,12 @@ TEST_F(LlvmLibcCoshfTest, InFloatRange) {
 }
 
 TEST_F(LlvmLibcCoshfTest, SmallValues) {
-  float x = float(FPBits(0x17800000U));
+  float x = FPBits(0x17800000U).get_val();
   float result = LIBC_NAMESPACE::coshf(x);
   EXPECT_MPFR_MATCH(mpfr::Operation::Cosh, x, result, 0.5);
   EXPECT_FP_EQ(1.0f, result);
 
-  x = float(FPBits(0x0040000U));
+  x = FPBits(0x0040000U).get_val();
   result = LIBC_NAMESPACE::coshf(x);
   EXPECT_MPFR_MATCH(mpfr::Operation::Cosh, x, result, 0.5);
   EXPECT_FP_EQ(1.0f, result);
diff --git a/libc/test/src/math/erff_test.cpp b/libc/test/src/math/erff_test.cpp
index 933f77c0b5a67d2..8ebde4ec24fb55c 100644
--- a/libc/test/src/math/erff_test.cpp
+++ b/libc/test/src/math/erff_test.cpp
@@ -36,7 +36,7 @@ TEST_F(LlvmLibcErffTest, TrickyInputs) {
       0x4004'1e6aU, // |x| = 0x1.083cd4p+1f
   };
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Erf, x,
                                    LIBC_NAMESPACE::erff(x), 0.5);
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Erf, -x,
diff --git a/libc/test/src/math/exhaustive/exhaustive_test.h b/libc/test/src/math/exhaustive/exhaustive_test.h
index dbb59e5269dc331..c4ae382688a03c6 100644
--- a/libc/test/src/math/exhaustive/exhaustive_test.h
+++ b/libc/test/src/math/exhaustive/exhaustive_test.h
@@ -55,7 +55,7 @@ struct UnaryOpChecker : public virtual LIBC_NAMESPACE::testing::Test {
     uint64_t failed = 0;
     do {
       FPBits xbits(bits);
-      FloatType x = FloatType(xbits);
+      FloatType x = xbits.get_val();
       bool correct =
           TEST_MPFR_MATCH_ROUNDING_SILENTLY(Op, x, FUNC(x), 0.5, rounding);
       failed += (!correct);
@@ -127,9 +127,8 @@ struct LlvmLibcExhaustiveMathTest
             msg << "Test failed for " << std::dec << failed_in_range
                 << " inputs in range: " << range_begin << " to " << range_end
                 << " [0x" << std::hex << range_begin << ", 0x" << range_end
-                << "), [" << std::hexfloat
-                << static_cast<FloatType>(FPBits(range_begin)) << ", "
-                << static_cast<FloatType>(FPBits(range_end)) << ")\n";
+                << "), [" << std::hexfloat << FPBits(range_begin).get_val()
+                << ", " << FPBits(range_end).get_val() << ")\n";
             std::cerr << msg.str() << std::flush;
 
             failed.fetch_add(failed_in_range);
diff --git a/libc/test/src/math/exhaustive/hypotf_test.cpp b/libc/test/src/math/exhaustive/hypotf_test.cpp
index df597563ab0cd3f..04da55d4d3a9fc6 100644
--- a/libc/test/src/math/exhaustive/hypotf_test.cpp
+++ b/libc/test/src/math/exhaustive/hypotf_test.cpp
@@ -31,10 +31,10 @@ struct HypotfChecker : public virtual LIBC_NAMESPACE::testing::Test {
     uint32_t xbits = start;
     uint64_t failed = 0;
     do {
-      float x = float(FPBits(xbits));
+      float x = FPBits(xbits).get_val();
       uint32_t ybits = Y_START;
       do {
-        float y = float(FPBits(ybits));
+        float y = FPBits(ybits).get_val();
         bool correct = TEST_FP_EQ(LIBC_NAMESPACE::fputil::hypot(x, y),
                                   LIBC_NAMESPACE::hypotf(x, y));
         // Using MPFR will be much slower.
diff --git a/libc/test/src/math/exhaustive/sincosf_test.cpp b/libc/test/src/math/exhaustive/sincosf_test.cpp
index 4104034d17c6f06..4d53d24f05328e1 100644
--- a/libc/test/src/math/exhaustive/sincosf_test.cpp
+++ b/libc/test/src/math/exhaustive/sincosf_test.cpp
@@ -26,7 +26,7 @@ struct SincosfChecker : public virtual LIBC_NAMESPACE::testing::Test {
     uint64_t failed = 0;
     do {
       FPBits xbits(bits);
-      FloatType x = FloatType(xbits);
+      FloatType x = xbits.get_val();
       FloatType sinx, cosx;
       LIBC_NAMESPACE::sincosf(x, &sinx, &cosx);
 
diff --git a/libc/test/src/math/exp10_test.cpp b/libc/test/src/math/exp10_test.cpp
index ec3925846dba4b1..e9990b3ed8e6d2d 100644
--- a/libc/test/src/math/exp10_test.cpp
+++ b/libc/test/src/math/exp10_test.cpp
@@ -79,7 +79,7 @@ TEST_F(LlvmLibcExp10Test, TrickyInputs) {
       0x4037000000000000, // x = 23
   };
   for (int i = 0; i < N; ++i) {
-    double x = double(FPBits(INPUTS[i]));
+    double x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
                                    LIBC_NAMESPACE::exp10(x), 0.5);
   }
diff --git a/libc/test/src/math/exp10f_test.cpp b/libc/test/src/math/exp10f_test.cpp
index e3151dafa942938..0866488935c202b 100644
--- a/libc/test/src/math/exp10f_test.cpp
+++ b/libc/test/src/math/exp10f_test.cpp
@@ -42,30 +42,31 @@ TEST_F(LlvmLibcExp10fTest, SpecialNumbers) {
 TEST_F(LlvmLibcExp10fTest, Overflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::exp10f(float(FPBits(0x7f7fffffU))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::exp10f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::exp10f(float(FPBits(0x43000000U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::exp10f(FPBits(0x43000000U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::exp10f(float(FPBits(0x43000001U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::exp10f(FPBits(0x43000001U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 }
 
 TEST_F(LlvmLibcExp10fTest, Underflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      0.0f, LIBC_NAMESPACE::exp10f(float(FPBits(0xff7fffffU))), FE_UNDERFLOW);
+      0.0f, LIBC_NAMESPACE::exp10f(FPBits(0xff7fffffU).get_val()),
+      FE_UNDERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
-  float x = float(FPBits(0xc2cffff8U));
+  float x = FPBits(0xc2cffff8U).get_val();
   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
                                  LIBC_NAMESPACE::exp10f(x), 0.5);
   EXPECT_MATH_ERRNO(ERANGE);
 
-  x = float(FPBits(0xc2d00008U));
+  x = FPBits(0xc2d00008U).get_val();
   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
                                  LIBC_NAMESPACE::exp10f(x), 0.5);
   EXPECT_MATH_ERRNO(ERANGE);
@@ -97,7 +98,7 @@ TEST_F(LlvmLibcExp10fTest, TrickyInputs) {
   };
   for (int i = 0; i < N; ++i) {
     libc_errno = 0;
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, x,
                                    LIBC_NAMESPACE::exp10f(x), 0.5);
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp10, -x,
@@ -109,7 +110,7 @@ TEST_F(LlvmLibcExp10fTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     libc_errno = 0;
diff --git a/libc/test/src/math/exp2_test.cpp b/libc/test/src/math/exp2_test.cpp
index 539ec7b9368f4c7..d66c9b757625d16 100644
--- a/libc/test/src/math/exp2_test.cpp
+++ b/libc/test/src/math/exp2_test.cpp
@@ -54,7 +54,7 @@ TEST_F(LlvmLibcExp2Test, TrickyInputs) {
       0xbc971547652b82fe, // x=-0x1.71547652b82fep-54
   };
   for (int i = 0; i < N; ++i) {
-    double x = double(FPBits(INPUTS[i]));
+    double x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2, x,
                                    LIBC_NAMESPACE::exp2(x), 0.5);
   }
diff --git a/libc/test/src/math/exp2f_test.cpp b/libc/test/src/math/exp2f_test.cpp
index 4c69c1d48d621c2..18607b1d0491040 100644
--- a/libc/test/src/math/exp2f_test.cpp
+++ b/libc/test/src/math/exp2f_test.cpp
@@ -43,15 +43,15 @@ TEST_F(LlvmLibcExp2fTest, SpecialNumbers) {
 TEST_F(LlvmLibcExp2fTest, Overflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::exp2f(float(FPBits(0x7f7fffffU))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::exp2f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::exp2f(float(FPBits(0x43000000U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::exp2f(FPBits(0x43000000U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::exp2f(float(FPBits(0x43000001U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::exp2f(FPBits(0x43000001U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 }
 
@@ -73,7 +73,7 @@ TEST_F(LlvmLibcExp2fTest, TrickyInputs) {
   };
   for (int i = 0; i < N; ++i) {
     libc_errno = 0;
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2, x,
                                    LIBC_NAMESPACE::exp2f(x), 0.5);
     EXPECT_MATH_ERRNO(0);
@@ -83,20 +83,20 @@ TEST_F(LlvmLibcExp2fTest, TrickyInputs) {
 TEST_F(LlvmLibcExp2fTest, Underflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      0.0f, LIBC_NAMESPACE::exp2f(float(FPBits(0xff7fffffU))), FE_UNDERFLOW);
+      0.0f, LIBC_NAMESPACE::exp2f(FPBits(0xff7fffffU).get_val()), FE_UNDERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
-  float x = float(FPBits(0xc3158000U));
+  float x = FPBits(0xc3158000U).get_val();
   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2, x,
                                  LIBC_NAMESPACE::exp2f(x), 0.5);
   EXPECT_MATH_ERRNO(0);
 
-  x = float(FPBits(0xc3160000U));
+  x = FPBits(0xc3160000U).get_val();
   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2, x,
                                  LIBC_NAMESPACE::exp2f(x), 0.5);
   EXPECT_MATH_ERRNO(ERANGE);
 
-  x = float(FPBits(0xc3165432U));
+  x = FPBits(0xc3165432U).get_val();
   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2, x,
                                  LIBC_NAMESPACE::exp2f(x), 0.5);
   EXPECT_MATH_ERRNO(ERANGE);
@@ -106,7 +106,7 @@ TEST_F(LlvmLibcExp2fTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     libc_errno = 0;
diff --git a/libc/test/src/math/exp_test.cpp b/libc/test/src/math/exp_test.cpp
index 1de2d7507acc303..454107f307d867f 100644
--- a/libc/test/src/math/exp_test.cpp
+++ b/libc/test/src/math/exp_test.cpp
@@ -52,7 +52,7 @@ TEST_F(LlvmLibcExpTest, TrickyInputs) {
       0xc0867a172ceb0990, // x=-0x1.67a172ceb099p+9
   };
   for (int i = 0; i < N; ++i) {
-    double x = double(FPBits(INPUTS[i]));
+    double x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x,
                                    LIBC_NAMESPACE::exp(x), 0.5);
   }
diff --git a/libc/test/src/math/expf_test.cpp b/libc/test/src/math/expf_test.cpp
index 521eba705b69fd0..0ac64ceec1c71c8 100644
--- a/libc/test/src/math/expf_test.cpp
+++ b/libc/test/src/math/expf_test.cpp
@@ -42,30 +42,30 @@ TEST_F(LlvmLibcExpfTest, SpecialNumbers) {
 TEST_F(LlvmLibcExpfTest, Overflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::expf(float(FPBits(0x7f7fffffU))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::expf(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::expf(float(FPBits(0x42cffff8U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::expf(FPBits(0x42cffff8U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::expf(float(FPBits(0x42d00008U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::expf(FPBits(0x42d00008U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 }
 
 TEST_F(LlvmLibcExpfTest, Underflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      0.0f, LIBC_NAMESPACE::expf(float(FPBits(0xff7fffffU))), FE_UNDERFLOW);
+      0.0f, LIBC_NAMESPACE::expf(FPBits(0xff7fffffU).get_val()), FE_UNDERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
-  float x = float(FPBits(0xc2cffff8U));
+  float x = FPBits(0xc2cffff8U).get_val();
   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x,
                                  LIBC_NAMESPACE::expf(x), 0.5);
   EXPECT_MATH_ERRNO(ERANGE);
 
-  x = float(FPBits(0xc2d00008U));
+  x = FPBits(0xc2d00008U).get_val();
   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x,
                                  LIBC_NAMESPACE::expf(x), 0.5);
   EXPECT_MATH_ERRNO(ERANGE);
@@ -77,27 +77,27 @@ TEST_F(LlvmLibcExpfTest, Borderline) {
   float x;
 
   libc_errno = 0;
-  x = float(FPBits(0x42affff8U));
+  x = FPBits(0x42affff8U).get_val();
   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x,
                                  LIBC_NAMESPACE::expf(x), 0.5);
   EXPECT_MATH_ERRNO(0);
 
-  x = float(FPBits(0x42b00008U));
+  x = FPBits(0x42b00008U).get_val();
   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x,
                                  LIBC_NAMESPACE::expf(x), 0.5);
   EXPECT_MATH_ERRNO(0);
 
-  x = float(FPBits(0xc2affff8U));
+  x = FPBits(0xc2affff8U).get_val();
   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x,
                                  LIBC_NAMESPACE::expf(x), 0.5);
   EXPECT_MATH_ERRNO(0);
 
-  x = float(FPBits(0xc2b00008U));
+  x = FPBits(0xc2b00008U).get_val();
   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x,
                                  LIBC_NAMESPACE::expf(x), 0.5);
   EXPECT_MATH_ERRNO(0);
 
-  x = float(FPBits(0xc236bd8cU));
+  x = FPBits(0xc236bd8cU).get_val();
   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x,
                                  LIBC_NAMESPACE::expf(x), 0.5);
   EXPECT_MATH_ERRNO(0);
@@ -107,7 +107,7 @@ TEST_F(LlvmLibcExpfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     libc_errno = 0;
diff --git a/libc/test/src/math/expm1_test.cpp b/libc/test/src/math/expm1_test.cpp
index ad53ffb6e8af1af..99ef8275eab739a 100644
--- a/libc/test/src/math/expm1_test.cpp
+++ b/libc/test/src/math/expm1_test.cpp
@@ -48,7 +48,7 @@ TEST_F(LlvmLibcExpm1Test, TrickyInputs) {
       0xc042b708872320dd, // x=-0x1.2b708872320ddp+5
   };
   for (int i = 0; i < N; ++i) {
-    double x = double(FPBits(INPUTS[i]));
+    double x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
                                    LIBC_NAMESPACE::expm1(x), 0.5);
   }
diff --git a/libc/test/src/math/expm1f_test.cpp b/libc/test/src/math/expm1f_test.cpp
index a9eaa4dbe5381a0..cc820803cc30bfb 100644
--- a/libc/test/src/math/expm1f_test.cpp
+++ b/libc/test/src/math/expm1f_test.cpp
@@ -42,26 +42,26 @@ TEST_F(LlvmLibcExpm1fTest, SpecialNumbers) {
 TEST_F(LlvmLibcExpm1fTest, Overflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::expm1f(float(FPBits(0x7f7fffffU))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::expm1f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::expm1f(float(FPBits(0x42cffff8U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::expm1f(FPBits(0x42cffff8U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::expm1f(float(FPBits(0x42d00008U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::expm1f(FPBits(0x42d00008U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 }
 
 TEST_F(LlvmLibcExpm1fTest, Underflow) {
   libc_errno = 0;
-  EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::expm1f(float(FPBits(0xff7fffffU))));
+  EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::expm1f(FPBits(0xff7fffffU).get_val()));
 
-  float x = float(FPBits(0xc2cffff8U));
+  float x = FPBits(0xc2cffff8U).get_val();
   EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::expm1f(x));
 
-  x = float(FPBits(0xc2d00008U));
+  x = FPBits(0xc2d00008U).get_val();
   EXPECT_FP_EQ(-1.0f, LIBC_NAMESPACE::expm1f(x));
 }
 
@@ -71,42 +71,42 @@ TEST_F(LlvmLibcExpm1fTest, Borderline) {
   float x;
 
   libc_errno = 0;
-  x = float(FPBits(0x42affff8U));
+  x = FPBits(0x42affff8U).get_val();
   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
                                  LIBC_NAMESPACE::expm1f(x), 0.5);
   EXPECT_MATH_ERRNO(0);
 
-  x = float(FPBits(0x42b00008U));
+  x = FPBits(0x42b00008U).get_val();
   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
                                  LIBC_NAMESPACE::expm1f(x), 0.5);
   EXPECT_MATH_ERRNO(0);
 
-  x = float(FPBits(0xc2affff8U));
+  x = FPBits(0xc2affff8U).get_val();
   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
                                  LIBC_NAMESPACE::expm1f(x), 0.5);
   EXPECT_MATH_ERRNO(0);
 
-  x = float(FPBits(0xc2b00008U));
+  x = FPBits(0xc2b00008U).get_val();
   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
                                  LIBC_NAMESPACE::expm1f(x), 0.5);
   EXPECT_MATH_ERRNO(0);
 
-  x = float(FPBits(0x3dc252ddU));
+  x = FPBits(0x3dc252ddU).get_val();
   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
                                  LIBC_NAMESPACE::expm1f(x), 0.5);
   EXPECT_MATH_ERRNO(0);
 
-  x = float(FPBits(0x3e35bec5U));
+  x = FPBits(0x3e35bec5U).get_val();
   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
                                  LIBC_NAMESPACE::expm1f(x), 0.5);
   EXPECT_MATH_ERRNO(0);
 
-  x = float(FPBits(0x942ed494U));
+  x = FPBits(0x942ed494U).get_val();
   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
                                  LIBC_NAMESPACE::expm1f(x), 0.5);
   EXPECT_MATH_ERRNO(0);
 
-  x = float(FPBits(0xbdc1c6cbU));
+  x = FPBits(0xbdc1c6cbU).get_val();
   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
                                  LIBC_NAMESPACE::expm1f(x), 0.5);
   EXPECT_MATH_ERRNO(0);
@@ -116,7 +116,7 @@ TEST_F(LlvmLibcExpm1fTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     libc_errno = 0;
diff --git a/libc/test/src/math/log10_test.cpp b/libc/test/src/math/log10_test.cpp
index 72224c24718005c..de9206f2daec2ef 100644
--- a/libc/test/src/math/log10_test.cpp
+++ b/libc/test/src/math/log10_test.cpp
@@ -66,7 +66,7 @@ TEST_F(LlvmLibcLog10Test, TrickyInputs) {
       0x30160580e7268a99, 0x5ca04103b7eaa345, 0x19ad77dc4a40093f,
       0x0000449fb5c8a96e};
   for (int i = 0; i < N; ++i) {
-    double x = double(FPBits(INPUTS[i]));
+    double x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log10, x,
                                    LIBC_NAMESPACE::log10(x), 0.5);
   }
diff --git a/libc/test/src/math/log10f_test.cpp b/libc/test/src/math/log10f_test.cpp
index 3448ea7570eec67..c38a5159682cfd0 100644
--- a/libc/test/src/math/log10f_test.cpp
+++ b/libc/test/src/math/log10f_test.cpp
@@ -59,7 +59,7 @@ TEST_F(LlvmLibcLog10fTest, TrickyInputs) {
   };
 
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log10, x,
                                    LIBC_NAMESPACE::log10f(x), 0.5);
   }
@@ -69,7 +69,7 @@ TEST_F(LlvmLibcLog10fTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log10, x,
                                    LIBC_NAMESPACE::log10f(x), 0.5);
   }
diff --git a/libc/test/src/math/log1p_test.cpp b/libc/test/src/math/log1p_test.cpp
index 5bec911937dca68..f70c0f87560cdd7 100644
--- a/libc/test/src/math/log1p_test.cpp
+++ b/libc/test/src/math/log1p_test.cpp
@@ -67,7 +67,7 @@ TEST_F(LlvmLibcLog1pTest, TrickyInputs) {
       0x5671e2f1628093e4, 0x73dac56e2bf1a951, 0x8001bc6879ea14c5,
   };
   for (int i = 0; i < N; ++i) {
-    double x = double(FPBits(INPUTS[i]));
+    double x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log1p, x,
                                    LIBC_NAMESPACE::log1p(x), 0.5);
   }
diff --git a/libc/test/src/math/log1pf_test.cpp b/libc/test/src/math/log1pf_test.cpp
index 16cdc4704cb8a35..37144838552cc0c 100644
--- a/libc/test/src/math/log1pf_test.cpp
+++ b/libc/test/src/math/log1pf_test.cpp
@@ -63,7 +63,7 @@ TEST_F(LlvmLibcLog1pfTest, TrickyInputs) {
       0xbf800000U, /*-1.0f*/
   };
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log1p, x,
                                    LIBC_NAMESPACE::log1pf(x), 0.5);
   }
@@ -73,7 +73,7 @@ TEST_F(LlvmLibcLog1pfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     libc_errno = 0;
diff --git a/libc/test/src/math/log2_test.cpp b/libc/test/src/math/log2_test.cpp
index b471b8eb540fe83..65eae58b3508a62 100644
--- a/libc/test/src/math/log2_test.cpp
+++ b/libc/test/src/math/log2_test.cpp
@@ -64,7 +64,7 @@ TEST_F(LlvmLibcLog2Test, TrickyInputs) {
       0x3fefbfdaa448ed98,
   };
   for (int i = 0; i < N; ++i) {
-    double x = double(FPBits(INPUTS[i]));
+    double x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log2, x,
                                    LIBC_NAMESPACE::log2(x), 0.5);
   }
diff --git a/libc/test/src/math/log2f_test.cpp b/libc/test/src/math/log2f_test.cpp
index aaa6320fb26b131..0793bf8a0409124 100644
--- a/libc/test/src/math/log2f_test.cpp
+++ b/libc/test/src/math/log2f_test.cpp
@@ -39,7 +39,7 @@ TEST_F(LlvmLibcLog2fTest, TrickyInputs) {
       0x3f80079bU, 0x3f81d0b5U, 0x3f82e602U, 0x3f83c98dU, 0x3f8cba39U};
 
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log2, x,
                                    LIBC_NAMESPACE::log2f(x), 0.5);
   }
@@ -49,7 +49,7 @@ TEST_F(LlvmLibcLog2fTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     libc_errno = 0;
diff --git a/libc/test/src/math/log_test.cpp b/libc/test/src/math/log_test.cpp
index e3f41e1e264a31e..457117c1757a7fc 100644
--- a/libc/test/src/math/log_test.cpp
+++ b/libc/test/src/math/log_test.cpp
@@ -63,7 +63,7 @@ TEST_F(LlvmLibcLogTest, TrickyInputs) {
       0x3fefbfdaa448ed98,
   };
   for (int i = 0; i < N; ++i) {
-    double x = double(FPBits(INPUTS[i]));
+    double x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log, x,
                                    LIBC_NAMESPACE::log(x), 0.5);
   }
diff --git a/libc/test/src/math/logf_test.cpp b/libc/test/src/math/logf_test.cpp
index c02e95cb6f80041..3ab67ba807823b0 100644
--- a/libc/test/src/math/logf_test.cpp
+++ b/libc/test/src/math/logf_test.cpp
@@ -71,7 +71,7 @@ TEST_F(LlvmLibcLogfTest, TrickyInputs) {
       0x7a17f30aU, /*0x1.2fe614p+117f*/
   };
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log, x,
                                    LIBC_NAMESPACE::logf(x), 0.5);
   }
@@ -81,7 +81,7 @@ TEST_F(LlvmLibcLogfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log, x,
diff --git a/libc/test/src/math/sin_test.cpp b/libc/test/src/math/sin_test.cpp
index cd9eeaff598feaf..69981ed22ee69f5 100644
--- a/libc/test/src/math/sin_test.cpp
+++ b/libc/test/src/math/sin_test.cpp
@@ -23,7 +23,7 @@ TEST_F(LlvmLibcSinTest, Range) {
   constexpr StorageType COUNT = 100'000;
   constexpr StorageType STEP = STORAGE_MAX / COUNT;
   for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    double x = double(FPBits(v));
+    double x = FPBits(v).get_val();
     // TODO: Expand the range of testing after range reduction is implemented.
     if (isnan(x) || isinf(x) || x > _2pi || x < -_2pi)
       continue;
diff --git a/libc/test/src/math/sincosf_test.cpp b/libc/test/src/math/sincosf_test.cpp
index fde707f892a9e28..76fda6354f63ac2 100644
--- a/libc/test/src/math/sincosf_test.cpp
+++ b/libc/test/src/math/sincosf_test.cpp
@@ -100,7 +100,7 @@ TEST_F(LlvmLibcSinCosfTest, InFloatRange) {
   constexpr uint32_t COUNT = 1'001;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits((v)));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
 
@@ -159,7 +159,7 @@ TEST_F(LlvmLibcSinCosfTest, SpecialValues) {
   };
 
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_SINCOS_MATCH_ALL_ROUNDING(x);
     EXPECT_SINCOS_MATCH_ALL_ROUNDING(-x);
   }
@@ -169,7 +169,7 @@ TEST_F(LlvmLibcSinCosfTest, SpecialValues) {
 // returns values furthest beyond its nominal upper bound of pi/4.
 TEST_F(LlvmLibcSinCosfTest, SDCOMP_26094) {
   for (uint32_t v : SDCOMP26094_VALUES) {
-    float x = float(FPBits((v)));
+    float x = FPBits(v).get_val();
     EXPECT_SINCOS_MATCH_ALL_ROUNDING(x);
     EXPECT_SINCOS_MATCH_ALL_ROUNDING(-x);
   }
diff --git a/libc/test/src/math/sinf_test.cpp b/libc/test/src/math/sinf_test.cpp
index 107b015512990bd..32afc4f1c60d117 100644
--- a/libc/test/src/math/sinf_test.cpp
+++ b/libc/test/src/math/sinf_test.cpp
@@ -47,7 +47,7 @@ TEST_F(LlvmLibcSinfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sin, x,
@@ -97,7 +97,7 @@ TEST_F(LlvmLibcSinfTest, SpecificBitPatterns) {
   };
 
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sin, x,
                                    LIBC_NAMESPACE::sinf(x), 0.5);
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sin, -x,
@@ -107,11 +107,11 @@ TEST_F(LlvmLibcSinfTest, SpecificBitPatterns) {
 
 // For small values, sin(x) is x.
 TEST_F(LlvmLibcSinfTest, SmallValues) {
-  float x = float(FPBits(0x1780'0000U));
+  float x = FPBits(0x1780'0000U).get_val();
   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sin, x,
                                  LIBC_NAMESPACE::sinf(x), 0.5);
 
-  x = float(FPBits(0x0040'0000U));
+  x = FPBits(0x0040'0000U).get_val();
   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sin, x,
                                  LIBC_NAMESPACE::sinf(x), 0.5);
 }
@@ -120,7 +120,7 @@ TEST_F(LlvmLibcSinfTest, SmallValues) {
 // returns values furthest beyond its nominal upper bound of pi/4.
 TEST_F(LlvmLibcSinfTest, SDCOMP_26094) {
   for (uint32_t v : SDCOMP26094_VALUES) {
-    float x = float(FPBits((v)));
+    float x = FPBits((v)).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sin, x,
                                    LIBC_NAMESPACE::sinf(x), 0.5);
   }
diff --git a/libc/test/src/math/sinhf_test.cpp b/libc/test/src/math/sinhf_test.cpp
index dc80a1b7aedf983..765fdc6c2bcc4d0 100644
--- a/libc/test/src/math/sinhf_test.cpp
+++ b/libc/test/src/math/sinhf_test.cpp
@@ -45,7 +45,7 @@ TEST_F(LlvmLibcSinhfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     ASSERT_MPFR_MATCH(mpfr::Operation::Sinh, x, LIBC_NAMESPACE::sinhf(x), 0.5);
@@ -54,12 +54,12 @@ TEST_F(LlvmLibcSinhfTest, InFloatRange) {
 
 // For small values, sinh(x) is x.
 TEST_F(LlvmLibcSinhfTest, SmallValues) {
-  float x = float(FPBits(uint32_t(0x17800000)));
+  float x = FPBits(uint32_t(0x17800000)).get_val();
   float result = LIBC_NAMESPACE::sinhf(x);
   EXPECT_MPFR_MATCH(mpfr::Operation::Sinh, x, result, 0.5);
   EXPECT_FP_EQ(x, result);
 
-  x = float(FPBits(uint32_t(0x00400000)));
+  x = FPBits(uint32_t(0x00400000)).get_val();
   result = LIBC_NAMESPACE::sinhf(x);
   EXPECT_MPFR_MATCH(mpfr::Operation::Sinh, x, result, 0.5);
   EXPECT_FP_EQ(x, result);
@@ -68,24 +68,24 @@ TEST_F(LlvmLibcSinhfTest, SmallValues) {
 TEST_F(LlvmLibcSinhfTest, Overflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::sinhf(float(FPBits(0x7f7fffffU))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::sinhf(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::sinhf(float(FPBits(0x42cffff8U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::sinhf(FPBits(0x42cffff8U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::sinhf(float(FPBits(0x42d00008U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::sinhf(FPBits(0x42d00008U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 }
 
 TEST_F(LlvmLibcSinhfTest, ExceptionalValues) {
-  float x = float(FPBits(uint32_t(0x3a12'85ffU)));
+  float x = FPBits(uint32_t(0x3a12'85ffU)).get_val();
   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sinh, x,
                                  LIBC_NAMESPACE::sinhf(x), 0.5);
 
-  x = -float(FPBits(uint32_t(0x3a12'85ffU)));
+  x = -FPBits(uint32_t(0x3a12'85ffU)).get_val();
   EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sinh, x,
                                  LIBC_NAMESPACE::sinhf(x), 0.5);
 }
diff --git a/libc/test/src/math/smoke/FDimTest.h b/libc/test/src/math/smoke/FDimTest.h
index 46df2b40e64bd1b..31df2f5607c2662 100644
--- a/libc/test/src/math/smoke/FDimTest.h
+++ b/libc/test/src/math/smoke/FDimTest.h
@@ -20,11 +20,11 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
   void test_na_n_arg(FuncPtr func) {
     EXPECT_FP_EQ(nan, func(nan, inf));
@@ -66,7 +66,7 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
          ++i, v += STEP, w -= STEP) {
-      T x = T(FPBits(v)), y = T(FPBits(w));
+      T x = FPBits(v).get_val(), y = FPBits(w).get_val();
       if (isnan(x) || isinf(x))
         continue;
       if (isnan(y) || isinf(y))
diff --git a/libc/test/src/math/smoke/FMaxTest.h b/libc/test/src/math/smoke/FMaxTest.h
index 372d9c5571d319f..98edc8e971e8167 100644
--- a/libc/test/src/math/smoke/FMaxTest.h
+++ b/libc/test/src/math/smoke/FMaxTest.h
@@ -56,7 +56,7 @@ template <typename T> class FMaxTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
          ++i, v += STEP, w -= STEP) {
-      T x = T(FPBits(v)), y = T(FPBits(w));
+      T x = FPBits(v).get_val(), y = FPBits(w).get_val();
       if (isnan(x) || isinf(x))
         continue;
       if (isnan(y) || isinf(y))
diff --git a/libc/test/src/math/smoke/FMinTest.h b/libc/test/src/math/smoke/FMinTest.h
index a51f30803ba82a9..834d757c85d047d 100644
--- a/libc/test/src/math/smoke/FMinTest.h
+++ b/libc/test/src/math/smoke/FMinTest.h
@@ -56,7 +56,7 @@ template <typename T> class FMinTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0, w = STORAGE_MAX; i <= COUNT;
          ++i, v += STEP, w -= STEP) {
-      T x = T(FPBits(v)), y = T(FPBits(w));
+      T x = FPBits(v).get_val(), y = FPBits(w).get_val();
       if (isnan(x) || isinf(x))
         continue;
       if (isnan(y) || isinf(y))
diff --git a/libc/test/src/math/smoke/FmaTest.h b/libc/test/src/math/smoke/FmaTest.h
index 106ba1405a96863..9d76d3bde31211a 100644
--- a/libc/test/src/math/smoke/FmaTest.h
+++ b/libc/test/src/math/smoke/FmaTest.h
@@ -21,11 +21,11 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
 public:
   void test_special_numbers(Func func) {
@@ -39,16 +39,16 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test {
     EXPECT_FP_EQ(func(inf, neg_inf, nan), nan);
 
     // Test underflow rounding up.
-    EXPECT_FP_EQ(
-        func(T(0.5), T(FPBits::min_subnormal()), T(FPBits::min_subnormal())),
-        T(FPBits(StorageType(2))));
+    EXPECT_FP_EQ(func(T(0.5), FPBits::min_subnormal().get_val(),
+                      FPBits::min_subnormal().get_val()),
+                 FPBits(StorageType(2)).get_val());
     // Test underflow rounding down.
     StorageType MIN_NORMAL = FPBits::min_normal().uintval();
-    T v = T(FPBits(MIN_NORMAL + StorageType(1)));
-    EXPECT_FP_EQ(func(T(1) / T(MIN_NORMAL << 1), v, T(FPBits::min_normal())),
-                 v);
+    T v = FPBits(MIN_NORMAL + StorageType(1)).get_val();
+    EXPECT_FP_EQ(
+        func(T(1) / T(MIN_NORMAL << 1), v, FPBits::min_normal().get_val()), v);
     // Test overflow.
-    T z = T(FPBits::max_normal());
+    T z = FPBits::max_normal().get_val();
     EXPECT_FP_EQ(func(T(1.75), z, -z), T(0.75) * z);
     // Exact cancellation.
     EXPECT_FP_EQ(func(T(3.0), T(5.0), -T(15.0)), T(0.0));
diff --git a/libc/test/src/math/smoke/HypotTest.h b/libc/test/src/math/smoke/HypotTest.h
index 5400fc0730d8a47..0f3b52d53f49c9d 100644
--- a/libc/test/src/math/smoke/HypotTest.h
+++ b/libc/test/src/math/smoke/HypotTest.h
@@ -22,16 +22,16 @@ class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
-  const T nan = T(FPBits::build_quiet_nan());
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-
-  const T max_normal = T(FPBits::max_normal());
-  const T min_normal = T(FPBits::min_normal());
-  const T max_subnormal = T(FPBits::max_subnormal());
-  const T min_subnormal = T(FPBits::min_subnormal());
+  const T nan = FPBits::build_quiet_nan().get_val();
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+
+  const T max_normal = FPBits::max_normal().get_val();
+  const T min_normal = FPBits::min_normal().get_val();
+  const T max_subnormal = FPBits::max_subnormal().get_val();
+  const T min_subnormal = FPBits::min_subnormal().get_val();
 
 public:
   void test_special_numbers(Func func) {
diff --git a/libc/test/src/math/smoke/ILogbTest.h b/libc/test/src/math/smoke/ILogbTest.h
index fe28fab9d777c99..fb8d77093eba3c9 100644
--- a/libc/test/src/math/smoke/ILogbTest.h
+++ b/libc/test/src/math/smoke/ILogbTest.h
@@ -26,11 +26,11 @@ class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
   void test_special_numbers(typename ILogbFunc<T>::Func func) {
     using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
     using Sign = LIBC_NAMESPACE::fputil::Sign;
-    EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero(Sign::POS))));
-    EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero(Sign::NEG))));
-    EXPECT_EQ(FP_ILOGBNAN, func(T(FPBits::build_quiet_nan())));
-    EXPECT_EQ(INT_MAX, func(T(FPBits::inf(Sign::POS))));
-    EXPECT_EQ(INT_MAX, func(T(FPBits::inf(Sign::NEG))));
+    EXPECT_EQ(FP_ILOGB0, func(FPBits::zero(Sign::POS).get_val()));
+    EXPECT_EQ(FP_ILOGB0, func(FPBits::zero(Sign::NEG).get_val()));
+    EXPECT_EQ(FP_ILOGBNAN, func(FPBits::build_quiet_nan().get_val()));
+    EXPECT_EQ(INT_MAX, func(FPBits::inf(Sign::POS).get_val()));
+    EXPECT_EQ(INT_MAX, func(FPBits::inf(Sign::NEG).get_val()));
   }
 
   template <typename T>
@@ -81,7 +81,7 @@ class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 10'001;
     constexpr StorageType STEP = (MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT;
     for (StorageType v = MIN_SUBNORMAL; v <= MAX_SUBNORMAL; v += STEP) {
-      T x = T(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x) || x == 0.0)
         continue;
 
@@ -100,7 +100,7 @@ class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 10'001;
     constexpr StorageType STEP = (MAX_NORMAL - MIN_NORMAL) / COUNT;
     for (StorageType v = MIN_NORMAL; v <= MAX_NORMAL; v += STEP) {
-      T x = T(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x) || x == 0.0)
         continue;
 
diff --git a/libc/test/src/math/smoke/LdExpTest.h b/libc/test/src/math/smoke/LdExpTest.h
index 08a14a90c122636..1d581f2c0a02fcb 100644
--- a/libc/test/src/math/smoke/LdExpTest.h
+++ b/libc/test/src/math/smoke/LdExpTest.h
@@ -25,11 +25,11 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
   // A normalized mantissa to be used with tests.
   static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234;
diff --git a/libc/test/src/math/smoke/LogbTest.h b/libc/test/src/math/smoke/LogbTest.h
index a2628273cecc976..e2698e2b7b81b73 100644
--- a/libc/test/src/math/smoke/LogbTest.h
+++ b/libc/test/src/math/smoke/LogbTest.h
@@ -72,7 +72,7 @@ template <typename T> class LogbTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'000;
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-      T x = static_cast<T>(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x) || x == 0.0l)
         continue;
 
diff --git a/libc/test/src/math/smoke/ModfTest.h b/libc/test/src/math/smoke/ModfTest.h
index ea7e36b67d11fa6..a73e5ae4298faab 100644
--- a/libc/test/src/math/smoke/ModfTest.h
+++ b/libc/test/src/math/smoke/ModfTest.h
@@ -84,7 +84,7 @@ template <typename T> class ModfTest : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 100'000;
     constexpr StorageType STEP = STORAGE_MAX / COUNT;
     for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-      T x = T(FPBits(v));
+      T x = FPBits(v).get_val();
       if (isnan(x) || isinf(x) || x == T(0.0))
         continue;
 
diff --git a/libc/test/src/math/smoke/NextAfterTest.h b/libc/test/src/math/smoke/NextAfterTest.h
index 859e2c74a36935d..d2870562b238d2d 100644
--- a/libc/test/src/math/smoke/NextAfterTest.h
+++ b/libc/test/src/math/smoke/NextAfterTest.h
@@ -34,11 +34,11 @@ class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
   static constexpr StorageType min_subnormal =
       FPBits::min_subnormal().uintval();
diff --git a/libc/test/src/math/smoke/NextTowardTest.h b/libc/test/src/math/smoke/NextTowardTest.h
index c9f07b993f04b5b..5bbc89b9e5f76f6 100644
--- a/libc/test/src/math/smoke/NextTowardTest.h
+++ b/libc/test/src/math/smoke/NextTowardTest.h
@@ -36,11 +36,11 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
   const long double to_zero = ToFPBits::zero().get_val();
   const long double to_neg_zero = ToFPBits::zero(Sign::NEG).get_val();
diff --git a/libc/test/src/math/smoke/RIntTest.h b/libc/test/src/math/smoke/RIntTest.h
index bd99e634badbdff..88c4c560fffaffa 100644
--- a/libc/test/src/math/smoke/RIntTest.h
+++ b/libc/test/src/math/smoke/RIntTest.h
@@ -31,11 +31,11 @@ class RIntTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
 public:
   void testSpecialNumbers(RIntFunc func) {
diff --git a/libc/test/src/math/smoke/RemQuoTest.h b/libc/test/src/math/smoke/RemQuoTest.h
index 739661f2d9619e4..e0fbe4ee935fb54 100644
--- a/libc/test/src/math/smoke/RemQuoTest.h
+++ b/libc/test/src/math/smoke/RemQuoTest.h
@@ -21,11 +21,11 @@ class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const T inf = T(FPBits::inf(Sign::POS));
-  const T neg_inf = T(FPBits::inf(Sign::NEG));
-  const T zero = T(FPBits::zero(Sign::POS));
-  const T neg_zero = T(FPBits::zero(Sign::NEG));
-  const T nan = T(FPBits::build_quiet_nan());
+  const T inf = FPBits::inf(Sign::POS).get_val();
+  const T neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const T zero = FPBits::zero(Sign::POS).get_val();
+  const T neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const T nan = FPBits::build_quiet_nan().get_val();
 
 public:
   typedef T (*RemQuoFunc)(T, T, int *);
diff --git a/libc/test/src/math/smoke/RoundToIntegerTest.h b/libc/test/src/math/smoke/RoundToIntegerTest.h
index 404155604645c5b..836f827c145045c 100644
--- a/libc/test/src/math/smoke/RoundToIntegerTest.h
+++ b/libc/test/src/math/smoke/RoundToIntegerTest.h
@@ -30,11 +30,11 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
   using StorageType = typename FPBits::StorageType;
   using Sign = LIBC_NAMESPACE::fputil::Sign;
 
-  const F zero = F(FPBits::zero(Sign::POS));
-  const F neg_zero = F(FPBits::zero(Sign::NEG));
-  const F inf = F(FPBits::inf(Sign::POS));
-  const F neg_inf = F(FPBits::inf(Sign::NEG));
-  const F nan = F(FPBits::build_quiet_nan());
+  const F zero = FPBits::zero(Sign::POS).get_val();
+  const F neg_zero = FPBits::zero(Sign::NEG).get_val();
+  const F inf = FPBits::inf(Sign::POS).get_val();
+  const F neg_inf = FPBits::inf(Sign::NEG).get_val();
+  const F nan = FPBits::build_quiet_nan().get_val();
 
   static constexpr StorageType MAX_SUBNORMAL =
       FPBits::max_subnormal().uintval();
@@ -119,7 +119,7 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
     constexpr StorageType COUNT = 1'000'001;
     constexpr StorageType STEP = (MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT;
     for (StorageType i = MIN_SUBNORMAL; i <= MAX_SUBNORMAL; i += STEP) {
-      F x = F(FPBits(i));
+      F x = FPBits(i).get_val();
       if (x == F(0.0))
         continue;
       // All subnormal numbers should round to zero.
diff --git a/libc/test/src/math/smoke/coshf_test.cpp b/libc/test/src/math/smoke/coshf_test.cpp
index 93fdd126896cf8b..aa224dcc156f090 100644
--- a/libc/test/src/math/smoke/coshf_test.cpp
+++ b/libc/test/src/math/smoke/coshf_test.cpp
@@ -41,14 +41,14 @@ TEST_F(LlvmLibcCoshfTest, SpecialNumbers) {
 TEST_F(LlvmLibcCoshfTest, Overflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::coshf(float(FPBits(0x7f7fffffU))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::coshf(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::coshf(float(FPBits(0x42cffff8U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::coshf(FPBits(0x42cffff8U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::coshf(float(FPBits(0x42d00008U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::coshf(FPBits(0x42d00008U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 }
diff --git a/libc/test/src/math/smoke/exp10f_test.cpp b/libc/test/src/math/smoke/exp10f_test.cpp
index 8b758dd3f62f995..d242edf04fb3706 100644
--- a/libc/test/src/math/smoke/exp10f_test.cpp
+++ b/libc/test/src/math/smoke/exp10f_test.cpp
@@ -43,14 +43,14 @@ TEST_F(LlvmLibcExp10fTest, SpecialNumbers) {
 TEST_F(LlvmLibcExp10fTest, Overflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::exp10f(float(FPBits(0x7f7fffffU))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::exp10f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::exp10f(float(FPBits(0x43000000U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::exp10f(FPBits(0x43000000U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::exp10f(float(FPBits(0x43000001U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::exp10f(FPBits(0x43000001U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 }
diff --git a/libc/test/src/math/smoke/exp2f_test.cpp b/libc/test/src/math/smoke/exp2f_test.cpp
index 6623d449aeebdf7..e4e56ed23bcffe1 100644
--- a/libc/test/src/math/smoke/exp2f_test.cpp
+++ b/libc/test/src/math/smoke/exp2f_test.cpp
@@ -45,14 +45,14 @@ TEST_F(LlvmLibcExp2fTest, SpecialNumbers) {
 TEST_F(LlvmLibcExp2fTest, Overflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::exp2f(float(FPBits(0x7f7fffffU))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::exp2f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::exp2f(float(FPBits(0x43000000U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::exp2f(FPBits(0x43000000U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::exp2f(float(FPBits(0x43000001U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::exp2f(FPBits(0x43000001U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 }
diff --git a/libc/test/src/math/smoke/expf_test.cpp b/libc/test/src/math/smoke/expf_test.cpp
index ff33e95f90427f1..24fc35b552ca2e4 100644
--- a/libc/test/src/math/smoke/expf_test.cpp
+++ b/libc/test/src/math/smoke/expf_test.cpp
@@ -39,14 +39,14 @@ TEST_F(LlvmLibcExpfTest, SpecialNumbers) {
 TEST_F(LlvmLibcExpfTest, Overflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::expf(float(FPBits(0x7f7fffffU))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::expf(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::expf(float(FPBits(0x42cffff8U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::expf(FPBits(0x42cffff8U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::expf(float(FPBits(0x42d00008U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::expf(FPBits(0x42d00008U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 }
diff --git a/libc/test/src/math/smoke/expm1f_test.cpp b/libc/test/src/math/smoke/expm1f_test.cpp
index 6999a987f9d6a68..3d6dae77ec00424 100644
--- a/libc/test/src/math/smoke/expm1f_test.cpp
+++ b/libc/test/src/math/smoke/expm1f_test.cpp
@@ -39,14 +39,14 @@ TEST_F(LlvmLibcExpm1fTest, SpecialNumbers) {
 TEST_F(LlvmLibcExpm1fTest, Overflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::expm1f(float(FPBits(0x7f7fffffU))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::expm1f(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::expm1f(float(FPBits(0x42cffff8U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::expm1f(FPBits(0x42cffff8U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::expm1f(float(FPBits(0x42d00008U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::expm1f(FPBits(0x42d00008U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 }
diff --git a/libc/test/src/math/smoke/sinhf_test.cpp b/libc/test/src/math/smoke/sinhf_test.cpp
index aa11ed9cbe10502..0563ccbf77aaaf9 100644
--- a/libc/test/src/math/smoke/sinhf_test.cpp
+++ b/libc/test/src/math/smoke/sinhf_test.cpp
@@ -40,11 +40,11 @@ TEST_F(LlvmLibcSinhfTest, SpecialNumbers) {
 
 // For small values, sinh(x) is x.
 TEST_F(LlvmLibcSinhfTest, SmallValues) {
-  float x = float(FPBits(uint32_t(0x17800000)));
+  float x = FPBits(uint32_t(0x17800000)).get_val();
   float result = LIBC_NAMESPACE::sinhf(x);
   EXPECT_FP_EQ(x, result);
 
-  x = float(FPBits(uint32_t(0x00400000)));
+  x = FPBits(uint32_t(0x00400000)).get_val();
   result = LIBC_NAMESPACE::sinhf(x);
   EXPECT_FP_EQ(x, result);
 }
@@ -52,14 +52,14 @@ TEST_F(LlvmLibcSinhfTest, SmallValues) {
 TEST_F(LlvmLibcSinhfTest, Overflow) {
   libc_errno = 0;
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::sinhf(float(FPBits(0x7f7fffffU))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::sinhf(FPBits(0x7f7fffffU).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::sinhf(float(FPBits(0x42cffff8U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::sinhf(FPBits(0x42cffff8U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 
   EXPECT_FP_EQ_WITH_EXCEPTION(
-      inf, LIBC_NAMESPACE::sinhf(float(FPBits(0x42d00008U))), FE_OVERFLOW);
+      inf, LIBC_NAMESPACE::sinhf(FPBits(0x42d00008U).get_val()), FE_OVERFLOW);
   EXPECT_MATH_ERRNO(ERANGE);
 }
diff --git a/libc/test/src/math/tan_test.cpp b/libc/test/src/math/tan_test.cpp
index 8fae425f96f8f22..9cdc7c4abd32cca 100644
--- a/libc/test/src/math/tan_test.cpp
+++ b/libc/test/src/math/tan_test.cpp
@@ -22,7 +22,7 @@ TEST_F(LlvmLibcTanTest, Range) {
   constexpr StorageType COUNT = 100'000;
   constexpr StorageType STEP = STORAGE_MAX / COUNT;
   for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    double x = double(FPBits(v));
+    double x = FPBits(v).get_val();
     // TODO: Expand the range of testing after range reduction is implemented.
     if (isnan(x) || isinf(x) || x > _2pi || x < -_2pi)
       continue;
diff --git a/libc/test/src/math/tanf_test.cpp b/libc/test/src/math/tanf_test.cpp
index 6005202e754b1bc..5621e819522fc45 100644
--- a/libc/test/src/math/tanf_test.cpp
+++ b/libc/test/src/math/tanf_test.cpp
@@ -47,7 +47,7 @@ TEST_F(LlvmLibcTanfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'000;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Tan, x,
@@ -115,7 +115,7 @@ TEST_F(LlvmLibcTanfTest, SpecificBitPatterns) {
   };
 
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Tan, x,
                                    LIBC_NAMESPACE::tanf(x), 0.5);
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Tan, -x,
@@ -127,7 +127,7 @@ TEST_F(LlvmLibcTanfTest, SpecificBitPatterns) {
 // returns values furthest beyond its nominal upper bound of pi/4.
 TEST_F(LlvmLibcTanfTest, SDCOMP_26094) {
   for (uint32_t v : SDCOMP26094_VALUES) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     ASSERT_MPFR_MATCH(mpfr::Operation::Tan, x, LIBC_NAMESPACE::tanf(x), 0.5);
   }
 }
diff --git a/libc/test/src/math/tanhf_test.cpp b/libc/test/src/math/tanhf_test.cpp
index 1dc736d369303ca..862ba6cc7eeb7a1 100644
--- a/libc/test/src/math/tanhf_test.cpp
+++ b/libc/test/src/math/tanhf_test.cpp
@@ -44,7 +44,7 @@ TEST_F(LlvmLibcTanhfTest, InFloatRange) {
   constexpr uint32_t COUNT = 100'001;
   constexpr uint32_t STEP = UINT32_MAX / COUNT;
   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
-    float x = float(FPBits(v));
+    float x = FPBits(v).get_val();
     if (isnan(x) || isinf(x))
       continue;
     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Tanh, x,
@@ -62,7 +62,7 @@ TEST_F(LlvmLibcTanhfTest, ExceptionalValues) {
   };
 
   for (int i = 0; i < N; ++i) {
-    float x = float(FPBits(INPUTS[i]));
+    float x = FPBits(INPUTS[i]).get_val();
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Tanh, x,
                                    LIBC_NAMESPACE::tanhf(x), 0.5);
     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Tanh, -x,
diff --git a/libc/test/src/stdlib/atof_test.cpp b/libc/test/src/stdlib/atof_test.cpp
index ed3d4c26308cb23..613b56d05091ec9 100644
--- a/libc/test/src/stdlib/atof_test.cpp
+++ b/libc/test/src/stdlib/atof_test.cpp
@@ -26,7 +26,7 @@ TEST(LlvmLibcAToFTest, SimpleTest) {
 
   libc_errno = 0;
   EXPECT_THAT(LIBC_NAMESPACE::atof("123"),
-              Succeeds<double>(static_cast<double>(expected_fp)));
+              Succeeds<double>(expected_fp.get_val()));
 }
 
 TEST(LlvmLibcAToFTest, FailedParsingTest) {
diff --git a/libc/test/src/stdlib/strtod_test.cpp b/libc/test/src/stdlib/strtod_test.cpp
index b1bdd89e41fd151..452a180d70cea65 100644
--- a/libc/test/src/stdlib/strtod_test.cpp
+++ b/libc/test/src/stdlib/strtod_test.cpp
@@ -50,10 +50,9 @@ class LlvmLibcStrToDTest : public LIBC_NAMESPACE::testing::Test,
     libc_errno = 0;
     double result = LIBC_NAMESPACE::strtod(inputString, &str_end);
     if (expectedErrno == 0)
-      EXPECT_THAT(result, Succeeds<double>(static_cast<double>(expected_fp)));
+      EXPECT_THAT(result, Succeeds<double>(expected_fp.get_val()));
     else
-      EXPECT_THAT(result, Fails<double>(expectedErrno,
-                                        static_cast<double>(expected_fp)));
+      EXPECT_THAT(result, Fails<double>(expectedErrno, expected_fp.get_val()));
     EXPECT_EQ(str_end - inputString, expectedStrLen);
   }
 };
diff --git a/libc/test/src/stdlib/strtof_test.cpp b/libc/test/src/stdlib/strtof_test.cpp
index 15a8a34ef4fb171..31b3f69f63a0c7a 100644
--- a/libc/test/src/stdlib/strtof_test.cpp
+++ b/libc/test/src/stdlib/strtof_test.cpp
@@ -48,7 +48,7 @@ class LlvmLibcStrToFTest : public LIBC_NAMESPACE::testing::Test,
     float result = LIBC_NAMESPACE::strtof(inputString, &str_end);
 
     EXPECT_EQ(str_end - inputString, expectedStrLen);
-    EXPECT_FP_EQ(result, static_cast<float>(expected_fp));
+    EXPECT_FP_EQ(result, expected_fp.get_val());
     EXPECT_EQ(libc_errno, expectedErrno);
   }
 };
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index 06a231c7d94d059..7cc18cfb6243890 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -451,7 +451,7 @@ class MPFRNumber {
     if (is_nan()) {
       if (FPBits<T>(input).is_nan())
         return MPFRNumber(0.0);
-      return MPFRNumber(static_cast<T>(FPBits<T>::inf()));
+      return MPFRNumber(FPBits<T>::inf().get_val());
     }
 
     int thisExponent = FPBits<T>(thisAsT).get_exponent();

>From 9b9fabaf649755129ba96a2a64fbe211c2cc60a0 Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Tue, 23 Jan 2024 15:09:22 +0000
Subject: [PATCH 2/2] put a necessary static_cast back

---
 libc/src/math/generic/hypotf.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/math/generic/hypotf.cpp b/libc/src/math/generic/hypotf.cpp
index 9a0805e390eb37f..4c94b3eb7b9889b 100644
--- a/libc/src/math/generic/hypotf.cpp
+++ b/libc/src/math/generic/hypotf.cpp
@@ -67,7 +67,7 @@ LLVM_LIBC_FUNCTION(float, hypotf, (float x, float y)) {
     }
   }
 
-  return result.get_val();
+  return static_cast<float>(result.get_val());
 }
 
 } // namespace LIBC_NAMESPACE



More information about the libc-commits mailing list