[libc-commits] [libc] [libc][NFC] unify nextafter and nexttoward code (PR #73698)
via libc-commits
libc-commits at lists.llvm.org
Thu Nov 30 11:48:16 PST 2023
================
@@ -144,59 +144,26 @@ LIBC_INLINE T ldexp(T x, int exp) {
return normal;
}
-template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T nextafter(T from, T to) {
- FPBits<T> from_bits(from);
- if (from_bits.is_nan())
- return from;
-
- FPBits<T> to_bits(to);
- if (to_bits.is_nan())
- return to;
-
- if (from == to)
- return to;
-
- using UIntType = typename FPBits<T>::UIntType;
- UIntType int_val = from_bits.uintval();
- UIntType sign_mask = (UIntType(1) << (sizeof(T) * 8 - 1));
- if (from != T(0.0)) {
- if ((from < to) == (from > T(0.0))) {
- ++int_val;
- } else {
- --int_val;
- }
- } else {
- int_val = (to_bits.uintval() & sign_mask) + UIntType(1);
- }
-
- UIntType exponent_bits = int_val & FloatProperties<T>::EXPONENT_MASK;
- if (exponent_bits == UIntType(0))
- raise_except_if_required(FE_UNDERFLOW | FE_INEXACT);
- else if (exponent_bits == FloatProperties<T>::EXPONENT_MASK)
- raise_except_if_required(FE_OVERFLOW | FE_INEXACT);
-
- return cpp::bit_cast<T>(int_val);
-}
-
-template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T>
-nexttoward(T from, long double to) {
+template <
+ typename T, typename U,
+ cpp::enable_if_t<cpp::is_floating_point_v<T> && cpp::is_floating_point_v<U>,
+ int> = 0>
+LIBC_INLINE T nextafter(T from, U to) {
FPBits<T> from_bits(from);
if (from_bits.is_nan())
return from;
- FPBits<long double> to_bits(to);
+ FPBits<U> to_bits(to);
if (to_bits.is_nan())
- return to;
+ return static_cast<T>(to);
- if ((long double)from == to)
- return to;
+ if (static_cast<U>(from) == to)
----------------
michaelrj-google wrote:
That would be good, yes. I'd say adding both a comment and a condition in the enableif such as `sizeof(T) >= sizeof(U)` would be the ideal solution.
https://github.com/llvm/llvm-project/pull/73698
More information about the libc-commits
mailing list