1#ifndef NEFORCE_CORE_NUMERIC_MATH_HPP__
2#define NEFORCE_CORE_NUMERIC_MATH_HPP__
14NEFORCE_BEGIN_NAMESPACE__
16NEFORCE_BEGIN_CONSTANTS__
39NEFORCE_INLINE17
constexpr decimal_t PI = 3.14159265358979323846L;
62 0, 1, 1, 2, 3, 5, 8, 13, 21,
63 34, 55, 89, 144, 233, 377, 610, 987, 1597,
64 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393,
65 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465,
66 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733,
67 1134903170, 1836311903, 2971215073, 4807526976, 7778742049};
73NEFORCE_END_CONSTANTS__
148NEFORCE_CONST_FUNCTION
constexpr int64_t safe_trunc(
const decimal_t x)
noexcept {
151 constexpr auto max_int64 =
static_cast<decimal_t>(max_val);
152 constexpr auto min_int64 =
static_cast<decimal_t>(min_val);
158 if (x >= max_int64) {
159 const auto result =
static_cast<int64_t>(x);
160 return (result == max_val && x <= max_int64) ? result : 0;
162 if (x <= min_int64) {
163 const auto result =
static_cast<int64_t>(x);
164 return (result == min_val && x >= min_int64) ? result : 0;
166 return static_cast<int64_t>(x);
174 constexpr decimal_t TWO_POW_63 = 9223372036854775808.0L;
175 if (x >= TWO_POW_63) {
176 return static_cast<uint64_t>(x - TWO_POW_63) + 9223372036854775808ULL;
191 if (n < constants::FIBONACCI_COUNT) {
192 return constants::FIBONACCI_LIST[n];
194 uint64_t a = constants::FIBONACCI_LIST[constants::FIBONACCI_COUNT - 2];
195 uint64_t b = constants::FIBONACCI_LIST[constants::FIBONACCI_COUNT - 1];
196 for (
uint32_t i = constants::FIBONACCI_COUNT; i <= n; ++i) {
224 return angular *
static_cast<T
>(constants::PI) /
static_cast<T
>(constants::SEMI_CIRCLE);
236 return radian * (
static_cast<T
>(constants::SEMI_CIRCLE) /
static_cast<T
>(constants::PI));
247 return x > T(0) ? x : -x;
271NEFORCE_CONST_FUNCTION
constexpr const T&
sum(
const T& x)
noexcept {
283template <
typename First,
typename... Rests,
enable_if_t<(
sizeof...(Rests) > 0),
int> = 0>
284constexpr decltype(
auto)
sum(First first, Rests... args) {
285 return first + _NEFORCE
sum(args...);
294template <
typename... Args,
enable_if_t<(
sizeof...(Args) > 0),
int> = 0>
295constexpr decltype(
auto)
average(Args... args) {
296 return _NEFORCE
sum(args...) /
sizeof...(Args);
306NEFORCE_CONSTEXPR14
int sign(
const T& value)
noexcept {
308 constexpr T zero = T(0);
326NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 T
gcd(
const T& m,
const T& n)
noexcept {
328 constexpr T zero = T(0);
345NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 T
lcm(
const T& m,
const T& n)
noexcept {
346 return (m / _NEFORCE
gcd(m, n)) * n;
363 NEFORCE_THROW_EXCEPTION(
math_exception(
"zero can not be dividend."));
382 NEFORCE_THROW_EXCEPTION(
math_exception(
"zero can not be dividend."));
397NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 T
power(
const T& x,
uint32_t n)
noexcept {
420 return power(constants::EULER, n);
452 }
else if (m < 1.0L) {
459 const decimal_t a = (m - 1.0L) / (m + 1.0L);
471 constexpr decimal_t LN2 = 0.69314718055994530941723212145817656807L;
472 return 2.0L * s +
static_cast<decimal_t>(k) * LN2;
484 NEFORCE_THROW_EXCEPTION(
math_exception(
"zero can not be dividend."));
511NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14
decimal_t
543NEFORCE_PURE_FUNCTION NEFORCE_CONSTEXPR14
decimal_t
555 const bool negative = x < 0.0L;
558 decimal_t guess = v > 1.0L ? v / 3.0L : v;
565 return negative ? -guess : guess;
593 if (x >= TWO_POW_64) {
599 if (pos >= TWO_POW_64) {
603 if (
absolute(pos - floor_pos) < constants::MACHINE_EPSILON) {
606 return -(floor_pos + 1.0L);
619 return floor(x * factor) / factor;
622NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14
bool is_even_integer(
const decimal_t x)
noexcept {
624 return absolute(half -
floor(half)) < constants::MACHINE_EPSILON;
639 if (x >= TWO_POW_64) {
643 if (
absolute(x - floor_x) < constants::MACHINE_EPSILON) {
646 return floor_x + 1.0L;
650 if (pos >= TWO_POW_64) {
654 return -
static_cast<decimal_t>(floor_pos);
666 return ceil(x * factor) / factor;
684 return (x < 0.0L) ? -int_part : int_part;
687 return (x < 0.0L) ? -(int_part + 1.0L) : (int_part + 1.0L);
690 if (is_even_integer(int_part)) {
691 return (x < 0.0L) ? -int_part : int_part;
693 return (x < 0.0L) ? -(int_part + 1.0L) : (int_part + 1.0L);
706 return floor(x * factor) / factor;
717 return ceil(x * factor) / factor;
749 return round(x * factor) / factor;
760 return (x < 0 ?
ceil(x * factor, 0) :
floor(x * factor, 0)) / factor;
772 return static_cast<decimal_t>(safe_trunc(x));
784 const decimal_t toler = constants::DEFAULT_TOLERANCE) {
785 if (
absolute(axis) < constants::MACHINE_EPSILON) {
825 return x - y *
round(x / y);
834 return x -
static_cast<decimal_t>(safe_trunc(x));
846 *int_ptr = safe_trunc(x);
847 return x -
static_cast<decimal_t>(*int_ptr);
853NEFORCE_CONSTEXPR14
void reduce_arg_sincos(
decimal_t& x,
int& quadrant)
noexcept {
861 constexpr decimal_t HALF_PI_HI = 1.57079632679489661923L;
862 constexpr decimal_t HALF_PI_LO = 6.12323399573676603587e-17L;
863 constexpr decimal_t INV_HALF_PI = 0.63661977236758134308L;
866 const auto k =
static_cast<int64_t>(kd);
867 quadrant =
static_cast<int>(quadrant + (k & 3)) & 3;
885 bool sin_done =
false, cos_done =
false;
887 while (!sin_done || !cos_done) {
889 term_sin = -term_sin * x2 / ((i + 1.0L) * (i + 2.0L));
896 term_cos = -term_cos * x2 / (i * (i + 1.0L));
925 inner::reduce_arg_sincos(x, quadrant);
928 inner::sincos_taylor(x, sin_x, cos_x);
955 inner::reduce_arg_sincos(x, quadrant);
957 inner::sincos_taylor(x, sin_x, cos_x);
983 inner::reduce_arg_sincos(x, quadrant);
985 inner::sincos_taylor(x, sin_x, cos_x);
1009 return (s > 0) ? inf : -inf;
1034 return (x > 0) ? constants::PI / 2 : -constants::PI / 2;
1037 bool negative = x < 0.0L;
1061 result = constants::PI / 2 - result;
1082 return constants::PI / 2;
1085 return -constants::PI / 2;
1106 return constants::PI;
1108 return constants::PI / 2 -
arcsine(x);
1113NEFORCE_END_NAMESPACE__
static constexpr T infinity() noexcept
获取正无穷大表示
static constexpr T max() noexcept
获取类型的最大值
static constexpr T quiet_nan() noexcept
获取安静nan表示
static constexpr T epsilon() noexcept
获取机器精度
static constexpr T min() noexcept
获取类型的最小值
constexpr size_t extent_v
extent的便捷变量模板
constexpr bool is_arithmetic_v
is_arithmetic的便捷变量模板
unsigned int uint32_t
32位无符号整数类型
long double decimal_t
扩展精度浮点数类型
long long int64_t
64位有符号整数类型
unsigned long long uint64_t
64位无符号整数类型
constexpr Iterator prev(Iterator iter, iter_difference_t< Iterator > n=1)
获取迭代器的前一个位置
constexpr decimal_t EULER
自然常数 e
constexpr decimal_t LOOSE_TOLERANCE
宽松容差
constexpr uint32_t FIBONACCI_COUNT
斐波那契数列预计算数量
constexpr decimal_t CIRCLE
全圆角度 360° (角度制)
constexpr decimal_t SEMI_CIRCLE
半圆角度 180° (角度制)
constexpr decimal_t PHI
黄金分割比 φ
constexpr decimal_t MACHINE_EPSILON
机器精度
constexpr uint64_t FIBONACCI_LIST[]
预计算的斐波那契数列
constexpr decimal_t TWO_PI_HI
高精度 2π 高位
constexpr decimal_t DEFAULT_TOLERANCE
默认容差
constexpr decimal_t PI
圆周率 π (弧度制)
constexpr decimal_t TWO_PI_LO
高精度 2π 低位
constexpr decimal_t truncate_bit(const decimal_t x, const uint32_t bit) noexcept
截断到指定位数
constexpr decimal_t float_apart(decimal_t x, int64_t *int_ptr) noexcept
分离整数和小数部分
constexpr decimal_t exponential(const uint32_t n) noexcept
计算e的n次幂
constexpr bool around_pi(const decimal_t x, const decimal_t toler=constants::LOOSE_TOLERANCE)
判断是否接近π的整数倍
constexpr enable_if_t< is_floating_point_v< T >, T > mod(const T x, const T y)
浮点数取模运算
constexpr decimal_t arccosine(const decimal_t x) noexcept
计算反余弦值
constexpr int sign(const T &value) noexcept
获取数值的符号
constexpr decimal_t floor(const decimal_t x) noexcept
向下取整
constexpr decimal_t sine(decimal_t x) noexcept
计算正弦值
constexpr decimal_t cube_root(const decimal_t x, const decimal_t precise=constants::DEFAULT_TOLERANCE) noexcept
计算立方根
constexpr decimal_t floor_bit(const decimal_t x, const uint32_t bit) noexcept
向下舍入到指定位数
constexpr decimal_t tangent(decimal_t x) noexcept
计算正切值
constexpr uint64_t factorial(const uint32_t n) noexcept
计算阶乘
constexpr decimal_t square_root(const decimal_t x, const decimal_t precise=constants::DEFAULT_TOLERANCE) noexcept
计算平方根
constexpr decimal_t ceil(const decimal_t x) noexcept
向上取整
constexpr decimal_t logarithm_e(const decimal_t x) noexcept
计算自然对数
constexpr decimal_t arctangent(decimal_t x) noexcept
计算反正切值
constexpr decimal_t cotangent(const decimal_t x)
计算余切值
constexpr decimal_t cosine(decimal_t x) noexcept
计算余弦值
constexpr decimal_t truncate(const decimal_t x, const int bit) noexcept
截断
constexpr uint64_t leonardo(const uint32_t n) noexcept
计算莱昂纳多数
constexpr T angular2radian(const T angular) noexcept
角度转弧度
constexpr T gcd(const T &m, const T &n) noexcept
计算最大公约数
constexpr decimal_t logarithm_2(const decimal_t x)
计算以2为底的对数
constexpr decltype(auto) average(Args... args)
计算平均值
constexpr T radian2angular(const T radian) noexcept
弧度转角度
constexpr decimal_t float_part(const decimal_t x) noexcept
获取小数部分
constexpr enable_if_t< is_signed_v< T >, T > absolute(const T x) noexcept
取绝对值(有符号数版本)
constexpr bool around_zero(const decimal_t x, const decimal_t toler=constants::LOOSE_TOLERANCE) noexcept
判断是否接近零
constexpr decimal_t logarithm(const decimal_t x, const uint32_t base)
计算任意底数的对数
constexpr decimal_t ceil_bit(const decimal_t x, const uint32_t bit) noexcept
向上舍入到指定位数
constexpr uint64_t fibonacci(const uint32_t n) noexcept
计算斐波那契数
constexpr decimal_t arcsine(const decimal_t x) noexcept
计算反正弦值
constexpr bool around_multiple(const decimal_t x, const decimal_t axis, const decimal_t toler=constants::DEFAULT_TOLERANCE)
判断是否接近某个倍数值
constexpr const T & sum(const T &x) noexcept
单参数求和
constexpr uint64_t safe_decimal_to_uint64(const decimal_t x) noexcept
将非负 decimal_t 安全转换为 uint64_t(避免 >= 2^63 时的 UB)
constexpr T power(const T &x, uint32_t n) noexcept
幂运算
constexpr decimal_t logarithm_10(const decimal_t x)
计算以10为底的对数
constexpr decimal_t round(const decimal_t x) noexcept
四舍五入
constexpr T lcm(const T &m, const T &n) noexcept
计算最小公倍数
constexpr decimal_t remainder(const decimal_t x, const decimal_t y) noexcept
计算余数
constexpr decimal_t round_bit(const decimal_t x, const uint32_t bit) noexcept
四舍五入到指定位数
constexpr bool is_infinity(const T x) noexcept
检查浮点数是否为无穷大
constexpr bool is_nan(const T x) noexcept
检查浮点数是否为NaN
constexpr bool is_finite(const T x) noexcept
检查浮点数是否为有限值
typename make_integer< Size, IsSigned >::type make_integer_t
make_integer的便捷别名
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名