25inline constexpr bool has_ieee_binary_interchange_layout_v =
40 detail::has_ieee_binary_interchange_layout_v<std::remove_cvref_t<T>>;
59template <UlpOrderedReal T>
61 std::conditional_t<
sizeof(T) == 4, std::uint32_t, std::conditional_t<
sizeof(T) == 8, std::uint64_t, __uint128_t>>;
63template <UlpOrderedReal T>
constexpr ulp_uint_t<T> ordered_ulp_key(T
value)
65 using UInt = ulp_uint_t<T>;
68 constexpr UInt SignBit = UInt{1} << (
sizeof(UInt) * 8 - 1);
69 UInt
const bits = std::bit_cast<UInt>(
value);
73 return (bits & SignBit) != 0 ? ~bits + UInt{1} : bits | SignBit;
82 constexpr UInt SignBit = UInt{1} << 78;
83 if (
value == T{0})
return SignBit;
85 T
const fraction = std::frexp(std::abs(
value), &exponent);
86 UInt significand =
static_cast<UInt
>(std::ldexp(fraction, 64));
89 if (exponent < MinExponent)
90 magnitude = significand >> (MinExponent - exponent);
92 magnitude = (UInt(exponent - MinExponent) << 63) + significand;
93 return std::signbit(
value) ? SignBit - magnitude : SignBit + magnitude;
97template <UlpOrderedReal T>
constexpr ulp_uint_t<T> ulp_distance_magnitude(T a, T b)
99 auto const ai = ordered_ulp_key(a);
100 auto const bi = ordered_ulp_key(b);
101 return ai < bi ? bi - ai : ai - bi;
115 if (std::isnan(a) || std::isnan(b))
117 return std::numeric_limits<long long>::max();
119 if (std::isinf(a) || std::isinf(b))
121 return (a == b) ? 0 : std::numeric_limits<long long>::max();
128 using UInt = detail::ulp_uint_t<T>;
129 auto const ai = detail::ordered_ulp_key(a);
130 auto const bi = detail::ordered_ulp_key(b);
131 UInt
const magnitude = ai < bi ? bi - ai : ai - bi;
132 constexpr auto MaxDistance = std::numeric_limits<long long>::max();
133 if (magnitude >=
static_cast<UInt
>(MaxDistance))
135 return bi > ai ? MaxDistance : -MaxDistance;
138 auto const signed_magnitude =
static_cast<long long>(magnitude);
139 return bi > ai ? signed_magnitude : -signed_magnitude;
160 static bool eq(T a, T b, std::int64_t max_ulps = 4)
162 if (max_ulps < 0 || std::isnan(a) || std::isnan(b))
170 if (std::isinf(a) || std::isinf(b))
175 using UInt = detail::ulp_uint_t<T>;
176 return detail::ulp_distance_magnitude(a, b) <=
static_cast<UInt
>(max_ulps);
188template <>
struct FloatingULP<
mpreal>
190 static bool eq(
mpreal const& a,
mpreal const& b, std::int64_t max_ulps = 4)
192 return detail::compare_mpreal(a, b, max_ulps).equal;
200inline long long float_distance(mpreal
const& a, mpreal
const& b) {
return detail::compare_mpreal(a, b, 0).distance; }
211 static bool eq(T
const& a, T
const& b, std::int64_t max_ulps = 4)
221 { FloatingULP<T>::eq(a, b) } -> std::same_as<bool>;
228 return (dist == std::numeric_limits<long long>::max()) ? std::numeric_limits<long long>::max() : std::llabs(dist);
231template <uni20::Complex T>
232 requires UlpOrderedReal<uni20::make_real_t<T>>
237 return std::max(dr, di);
Owning exact rational or finite-precision MPFR real, with eager arithmetic.
Definition mpreal.hpp:74
Concept for complex scalar types.
Definition scalar_concepts.hpp:75
Concept for real scalar types (float, double, etc.).
Definition scalar_concepts.hpp:69
Real scalar stored in an IEEE binary32, binary64, or binary128 interchange representation.
Definition floating_eq.hpp:37
Concept satisfied if T can be compared in ULPs.
Definition floating_eq.hpp:220
Real scalar with an implemented ordering of adjacent representable values.
Definition floating_eq.hpp:47
locale_t value
Definition data_table.cpp:49
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
Definition mpreal_ulp.hpp:8
long long float_abs_distance(T a, T b)
Return the absolute diagnostic ULP distance between two real scalars.
Definition floating_eq.hpp:225
long long float_distance(T a, T b)
Return the signed distance in ULPs between two supported real scalars.
Definition floating_eq.hpp:113
static bool eq(T const &a, T const &b, std::int64_t max_ulps=4)
Definition floating_eq.hpp:211
static bool eq(T a, T b, std::int64_t max_ulps=4)
Definition floating_eq.hpp:160
Compare floating point or complex values within a given ULP tolerance.
Definition floating_eq.hpp:154
Project-level numeric limits customization point.
Definition numeric_limits.hpp:16