12namespace uni20::detail::native_math
15concept NativeReal = std::same_as<T, float> || std::same_as<T, double> || std::same_as<T, long double>
17 || std::same_as<T, uni20::float128>
23 R lower = std::floor(x);
24 R fraction = x - lower;
25 if (fraction > R(0.5) || (fraction == R(0.5) && std::fmod(lower, R(2)) != R(0))) lower += R(1);
26 return lower == R(0) ? std::copysign(lower, x) : lower;
29template <NativeReal R> frexp_result<R>
frexp(R x)
31 if (!std::isfinite(x) || x == R(0))
return {x, 0};
33 R fraction = std::frexp(x, &exponent);
34 return {fraction, exponent};
36template <NativeReal R> modf_result<R>
modf(R x)
39 R fraction = std::modf(x, &integer);
40 return {fraction, integer};
42template <NativeReal R> remquo_result<R>
remquo(R x, R y)
44 if (!std::isfinite(x) || std::isnan(y) || y == R(0))
return {numeric_limits<R>::quiet_NaN(), 0};
46 R
remainder = std::remquo(x, y, "ient);
49template <NativeReal R> std::int64_t
ilogb(R x)
51 if (!std::isfinite(x) || x == R(0))
throw std::domain_error(
"ilogb requires a finite nonzero value");
52 return native_math::frexp(x).exponent - 1;
54template <NativeReal R, MathInteger I> R
ldexp(R x, I exponent)
58 auto n = std::clamp<std::int64_t>(math_integer(exponent), numeric_limits<int>::min(), numeric_limits<int>::max());
59 return std::ldexp(x,
static_cast<int>(n));
61template <NativeReal R, MathInteger I> R
scalbn(R x, I exponent) {
return native_math::ldexp(x, exponent); }
63template <NativeReal R, MathInteger I> R
pown(R x, I
value)
65 auto exponent = math_integer(
value);
66 std::uint64_t
magnitude = exponent < 0 ? std::uint64_t(0) - std::uint64_t(exponent) :
std::uint64_t(exponent);
68 if (exponent < 0) x = result / x;
71 if (magnitude & 1) result *= x;
73 if (magnitude) x *= x;
77template <NativeReal R, MathInteger I> R
rootn(R x, I
value)
80 if (
degree == 0)
return numeric_limits<R>::quiet_NaN();
82 if (
degree == -1)
return R(1) / x;
83 bool odd =
degree % 2 != 0;
84 if (std::signbit(x) && !odd && x != R(0))
return numeric_limits<R>::quiet_NaN();
88 result = std::sqrt(magnitude);
90 result = std::cbrt(magnitude);
93 if (
degree < 0) result = R(1) / result;
94 return odd ? std::copysign(result, x) : result;
96template <NativeReal R> sincos_result<R>
sincos(R x) {
return {std::sin(x), std::cos(x)}; }
97template <NativeReal R> sinhcosh_result<R>
sinhcosh(R x) {
return {std::sinh(x), std::cosh(x)}; }
99template <NativeReal R, NativeReal S> R
copysign(R magnitude, S sign)
101 return std::copysign(magnitude, std::signbit(sign) ? R(-1) : R(1));
103template <NativeReal R, NativeReal S>
auto fmin(R a, S b)
105 auto result = std::fmin(a, b);
106 if (a == 0 && b == 0)
return std::copysign(result,
decltype(result)((std::signbit(a) || std::signbit(b)) ? -1 : 1));
109template <NativeReal R, NativeReal S>
auto fmax(R a, S b)
111 auto result = std::fmax(a, b);
112 if (a == 0 && b == 0)
return std::copysign(result,
decltype(result)((std::signbit(a) && std::signbit(b)) ? -1 : 1));
115template <NativeReal R> R
next_up(R x) {
return std::nextafter(x, numeric_limits<R>::infinity()); }
116template <NativeReal R> R
next_down(R x) {
return std::nextafter(x, -numeric_limits<R>::infinity()); }
117template <NativeReal R, NativeReal S> R
nextafter(R x, S direction)
119 if (std::isnan(x) || std::isnan(direction))
return numeric_limits<R>::quiet_NaN();
120 if (x == direction)
return native_math::copysign(x, direction);
121 return x < direction ? native_math::next_up(x) : native_math::
next_down(x);
locale_t value
Definition data_table.cpp:49
DiagnosticMagnitude< R > magnitude(R const &value)
Definition gmres_diagnostics.hpp:98
constexpr detail::scalar_math::nextafter_fn nextafter
Adjacent value on the first operand grid toward the direction operand.
Definition math.hpp:549
constexpr detail::scalar_math::pown_fn pown
Integer power with scalar-specific rounding.
Definition math.hpp:529
constexpr detail::scalar_math::remquo_fn remquo
Nearest-even remainder and signed low three quotient bits.
Definition math.hpp:539
constexpr detail::scalar_math::scalbn_fn scalbn
Binary scaling with a signed 64-bit exponent.
Definition math.hpp:533
constexpr detail::scalar_math::modf_fn modf
Signed fractional and integral parts as an owning result.
Definition math.hpp:537
constexpr detail::scalar_math::ldexp_fn ldexp
Multiply by a power of two using the scalar's exponent interface.
Definition math.hpp:511
constexpr detail::scalar_math::ilogb_fn ilogb
Binary exponent of a finite nonzero value; throws otherwise.
Definition math.hpp:545
constexpr detail::scalar_math::sinhcosh_fn sinhcosh
Hyperbolic sine and cosine at one input.
Definition math.hpp:543
constexpr detail::scalar_math::next_up_fn next_up
Adjacent value toward positive infinity.
Definition math.hpp:551
constexpr detail::scalar_math::rootn_fn rootn
Real integer-order root; negative orders give reciprocal roots.
Definition math.hpp:531
constexpr detail::scalar_math::fmin_fn fmin
Minimum, preferring the numeric operand over a NaN.
Definition math.hpp:559
constexpr detail::scalar_math::next_down_fn next_down
Adjacent value toward negative infinity.
Definition math.hpp:553
constexpr detail::scalar_math::fmax_fn fmax
Maximum, preferring the numeric operand over a NaN.
Definition math.hpp:561
constexpr detail::scalar_math::sincos_fn sincos
Sine and cosine at one input.
Definition math.hpp:541
constexpr detail::scalar_math::round_even_fn round_even
Nearest integer with ties to even.
Definition math.hpp:527
constexpr detail::scalar_math::frexp_fn frexp
Binary fraction and exponent as an owning result.
Definition math.hpp:535
constexpr detail::scalar_math::copysign_fn copysign
Copy the sign while retaining the magnitude operand type and precision.
Definition math.hpp:547
auto degree(QNum const &q) -> int
Return the integral degree of a quantum number.
Definition qnum.hpp:270
exact_rational pow(X const &base, Y const &power)
Evaluate a rational power exactly when its real result is rational.
Definition exact_rational.hpp:337
mpreal remainder(mpreal const &a, mpreal const &b)
Nearest-even-quotient remainder; exact operands retain exact rational results.
Definition mpreal_functions.hpp:534