From 1308cb4e2db1eb117b53372bc4fe964cf2d96813 Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 1 Dec 2021 13:52:38 +0800 Subject: =?UTF-8?q?*fpm=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=BA=9Bfloat=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E7=9A=84=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/ThirdParty/fpm/include/fpm/fixed.hpp | 311 ++++++++++++++++------------ Client/ThirdParty/fpm/include/fpm/math.hpp | 2 +- 2 files changed, 181 insertions(+), 132 deletions(-) (limited to 'Client/ThirdParty') diff --git a/Client/ThirdParty/fpm/include/fpm/fixed.hpp b/Client/ThirdParty/fpm/include/fpm/fixed.hpp index 9feff29..b900dd0 100644 --- a/Client/ThirdParty/fpm/include/fpm/fixed.hpp +++ b/Client/ThirdParty/fpm/include/fpm/fixed.hpp @@ -36,34 +36,34 @@ namespace fpm // Converts an integral number to the fixed-point type. // Like static_cast, this truncates bits that don't fit. template ::value>::type* = nullptr> - constexpr inline explicit fixed(T val) noexcept + constexpr inline /*explicit*/ fixed(T val) noexcept : m_value(static_cast(val * FRACTION_MULT)) {} // Converts an floating-point number to the fixed-point type. // Like static_cast, this truncates bits that don't fit. template ::value>::type* = nullptr> - constexpr inline explicit fixed(T val) noexcept + constexpr inline /*explicit*/ fixed(T val) noexcept : m_value(static_cast((val >= 0.0) ? (val * FRACTION_MULT + T{0.5}) : (val * FRACTION_MULT - T{0.5}))) {} // Constructs from another fixed-point type with possibly different underlying representation. // Like static_cast, this truncates bits that don't fit. template - constexpr inline explicit fixed(fixed val) noexcept + constexpr inline /*explicit*/ fixed(fixed val) noexcept : m_value(from_fixed_point(val.raw_value()).raw_value()) {} // Explicit conversion to a floating-point type template ::value>::type* = nullptr> - constexpr inline explicit operator T() const noexcept + constexpr inline /*explicit*/ operator T() const noexcept { return static_cast(m_value) / FRACTION_MULT; } // Explicit conversion to an integral type template ::value>::type* = nullptr> - constexpr inline explicit operator T() const noexcept + constexpr inline /*explicit*/ operator T() const noexcept { return static_cast(m_value / FRACTION_MULT); } @@ -248,6 +248,13 @@ namespace fpm return fixed(x) *= y; } + template + constexpr inline fixed operator*(const fixed& x, T y) noexcept + { + fixed r = y; + return fixed(x) *= r; + } + template ::value>::type* = nullptr> constexpr inline fixed operator*(const fixed& x, T y) noexcept { @@ -270,6 +277,13 @@ namespace fpm return fixed(x) /= y; } + template + constexpr inline fixed operator/(const fixed& x, T y) noexcept + { + fixed r = y; + return fixed(x) /= r; + } + template ::value>::type* = nullptr> constexpr inline fixed operator/(const fixed& x, T y) noexcept { @@ -292,30 +306,65 @@ namespace fpm return x.raw_value() == y.raw_value(); } + template + constexpr inline bool operator==(const fixed& x, T y) noexcept + { + fixed r = y; + return x.raw_value() == r.raw_value(); + } + template constexpr inline bool operator!=(const fixed& x, const fixed& y) noexcept { return x.raw_value() != y.raw_value(); } + template + constexpr inline bool operator!=(const fixed& x, T y) noexcept + { + fixed r = y; + return x.raw_value() != r.raw_value(); + } + template constexpr inline bool operator<(const fixed& x, const fixed& y) noexcept { return x.raw_value() < y.raw_value(); } + template + constexpr inline bool operator<(const fixed& x, T y) noexcept + { + fixed r = y; + return x.raw_value() < r.raw_value(); + } + template constexpr inline bool operator>(const fixed& x, const fixed& y) noexcept { return x.raw_value() > y.raw_value(); } + template + constexpr inline bool operator>(const fixed& x, T y) noexcept + { + fixed r = y; + return x.raw_value() > r.raw_value(); + } + template constexpr inline bool operator<=(const fixed& x, const fixed& y) noexcept { return x.raw_value() <= y.raw_value(); } + template + constexpr inline bool operator<=(const fixed& x, T y) noexcept + { + fixed r = y; + return x.raw_value() <= r.raw_value(); + } + template constexpr inline bool operator>=(const fixed& x, const fixed& y) noexcept { @@ -324,21 +373,21 @@ namespace fpm namespace detail { - // Number of base-10 digits required to fully represent a number of bits - static constexpr int max_digits10(int bits) - { - // 8.24 fixed-point equivalent of (int)ceil(bits * std::log10(2)); - using T = long long; - return static_cast((T{bits} * 5050445 + (T{1} << 24) - 1) >> 24); - } + // Number of base-10 digits required to fully represent a number of bits + static constexpr int max_digits10(int bits) + { + // 8.24 fixed-point equivalent of (int)ceil(bits * std::log10(2)); + using T = long long; + return static_cast((T{bits} * 5050445 + (T{1} << 24) - 1) >> 24); + } - // Number of base-10 digits that can be fully represented by a number of bits - static constexpr int digits10(int bits) - { - // 8.24 fixed-point equivalent of (int)(bits * std::log10(2)); - using T = long long; - return static_cast((T{bits} * 5050445) >> 24); - } + // Number of base-10 digits that can be fully represented by a number of bits + static constexpr int digits10(int bits) + { + // 8.24 fixed-point equivalent of (int)(bits * std::log10(2)); + using T = long long; + return static_cast((T{bits} * 5050445) >> 24); + } } // namespace detail @@ -348,127 +397,127 @@ namespace fpm namespace std { -template -struct hash> -{ - using argument_type = fpm::fixed; - using result_type = std::size_t; - - result_type operator()(argument_type arg) const noexcept(noexcept(std::declval>()(arg.raw_value()))) { - return m_hash(arg.raw_value()); - } + template + struct hash> + { + using argument_type = fpm::fixed; + using result_type = std::size_t; -private: - std::hash m_hash; -}; + result_type operator()(argument_type arg) const noexcept(noexcept(std::declval>()(arg.raw_value()))) { + return m_hash(arg.raw_value()); + } -template -struct numeric_limits> -{ - static constexpr bool is_specialized = true; - static constexpr bool is_signed = std::numeric_limits::is_signed; - static constexpr bool is_integer = false; - static constexpr bool is_exact = true; - static constexpr bool has_infinity = false; - static constexpr bool has_quiet_NaN = false; - static constexpr bool has_signaling_NaN = false; - static constexpr bool has_denorm = std::denorm_absent; - static constexpr bool has_denorm_loss = false; - static constexpr std::float_round_style round_style = std::round_to_nearest; - static constexpr bool is_iec_559 = false; - static constexpr bool is_bounded = true; - static constexpr bool is_modulo = std::numeric_limits::is_modulo; - static constexpr int digits = std::numeric_limits::digits; - - // Any number with `digits10` significant base-10 digits (that fits in - // the range of the type) is guaranteed to be convertible from text and - // back without change. Worst case, this is 0.000...001, so we can only - // guarantee this case. Nothing more. - static constexpr int digits10 = 1; - - // This is equal to max_digits10 for the integer and fractional part together. - static constexpr int max_digits10 = - fpm::detail::max_digits10(std::numeric_limits::digits - F) + fpm::detail::max_digits10(F); - - static constexpr int radix = 2; - static constexpr int min_exponent = 1 - F; - static constexpr int min_exponent10 = -fpm::detail::digits10(F); - static constexpr int max_exponent = std::numeric_limits::digits - F; - static constexpr int max_exponent10 = fpm::detail::digits10(std::numeric_limits::digits - F); - static constexpr bool traps = true; - static constexpr bool tinyness_before = false; - - static constexpr fpm::fixed lowest() noexcept { - return fpm::fixed::from_raw_value(std::numeric_limits::lowest()); + private: + std::hash m_hash; }; - static constexpr fpm::fixed min() noexcept { - return lowest(); - } + template + struct numeric_limits> + { + static constexpr bool is_specialized = true; + static constexpr bool is_signed = std::numeric_limits::is_signed; + static constexpr bool is_integer = false; + static constexpr bool is_exact = true; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr bool has_denorm = std::denorm_absent; + static constexpr bool has_denorm_loss = false; + static constexpr std::float_round_style round_style = std::round_to_nearest; + static constexpr bool is_iec_559 = false; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = std::numeric_limits::is_modulo; + static constexpr int digits = std::numeric_limits::digits; + + // Any number with `digits10` significant base-10 digits (that fits in + // the range of the type) is guaranteed to be convertible from text and + // back without change. Worst case, this is 0.000...001, so we can only + // guarantee this case. Nothing more. + static constexpr int digits10 = 1; + + // This is equal to max_digits10 for the integer and fractional part together. + static constexpr int max_digits10 = + fpm::detail::max_digits10(std::numeric_limits::digits - F) + fpm::detail::max_digits10(F); + + static constexpr int radix = 2; + static constexpr int min_exponent = 1 - F; + static constexpr int min_exponent10 = -fpm::detail::digits10(F); + static constexpr int max_exponent = std::numeric_limits::digits - F; + static constexpr int max_exponent10 = fpm::detail::digits10(std::numeric_limits::digits - F); + static constexpr bool traps = true; + static constexpr bool tinyness_before = false; + + static constexpr fpm::fixed lowest() noexcept { + return fpm::fixed::from_raw_value(std::numeric_limits::lowest()); + }; + + static constexpr fpm::fixed min() noexcept { + return lowest(); + } - static constexpr fpm::fixed max() noexcept { - return fpm::fixed::from_raw_value(std::numeric_limits::max()); - }; + static constexpr fpm::fixed max() noexcept { + return fpm::fixed::from_raw_value(std::numeric_limits::max()); + }; - static constexpr fpm::fixed epsilon() noexcept { - return fpm::fixed::from_raw_value(1); - }; + static constexpr fpm::fixed epsilon() noexcept { + return fpm::fixed::from_raw_value(1); + }; - static constexpr fpm::fixed round_error() noexcept { - return fpm::fixed(1) / 2; + static constexpr fpm::fixed round_error() noexcept { + return fpm::fixed(1) / 2; + }; + + static constexpr fpm::fixed denorm_min() noexcept { + return min(); + } }; - static constexpr fpm::fixed denorm_min() noexcept { - return min(); - } -}; - -template -constexpr bool numeric_limits>::is_specialized; -template -constexpr bool numeric_limits>::is_signed; -template -constexpr bool numeric_limits>::is_integer; -template -constexpr bool numeric_limits>::is_exact; -template -constexpr bool numeric_limits>::has_infinity; -template -constexpr bool numeric_limits>::has_quiet_NaN; -template -constexpr bool numeric_limits>::has_signaling_NaN; -template -constexpr bool numeric_limits>::has_denorm; -template -constexpr bool numeric_limits>::has_denorm_loss; -template -constexpr std::float_round_style numeric_limits>::round_style; -template -constexpr bool numeric_limits>::is_iec_559; -template -constexpr bool numeric_limits>::is_bounded; -template -constexpr bool numeric_limits>::is_modulo; -template -constexpr int numeric_limits>::digits; -template -constexpr int numeric_limits>::digits10; -template -constexpr int numeric_limits>::max_digits10; -template -constexpr int numeric_limits>::radix; -template -constexpr int numeric_limits>::min_exponent; -template -constexpr int numeric_limits>::min_exponent10; -template -constexpr int numeric_limits>::max_exponent; -template -constexpr int numeric_limits>::max_exponent10; -template -constexpr bool numeric_limits>::traps; -template -constexpr bool numeric_limits>::tinyness_before; + template + constexpr bool numeric_limits>::is_specialized; + template + constexpr bool numeric_limits>::is_signed; + template + constexpr bool numeric_limits>::is_integer; + template + constexpr bool numeric_limits>::is_exact; + template + constexpr bool numeric_limits>::has_infinity; + template + constexpr bool numeric_limits>::has_quiet_NaN; + template + constexpr bool numeric_limits>::has_signaling_NaN; + template + constexpr bool numeric_limits>::has_denorm; + template + constexpr bool numeric_limits>::has_denorm_loss; + template + constexpr std::float_round_style numeric_limits>::round_style; + template + constexpr bool numeric_limits>::is_iec_559; + template + constexpr bool numeric_limits>::is_bounded; + template + constexpr bool numeric_limits>::is_modulo; + template + constexpr int numeric_limits>::digits; + template + constexpr int numeric_limits>::digits10; + template + constexpr int numeric_limits>::max_digits10; + template + constexpr int numeric_limits>::radix; + template + constexpr int numeric_limits>::min_exponent; + template + constexpr int numeric_limits>::min_exponent10; + template + constexpr int numeric_limits>::max_exponent; + template + constexpr int numeric_limits>::max_exponent10; + template + constexpr bool numeric_limits>::traps; + template + constexpr bool numeric_limits>::tinyness_before; } diff --git a/Client/ThirdParty/fpm/include/fpm/math.hpp b/Client/ThirdParty/fpm/include/fpm/math.hpp index cf45297..3943940 100644 --- a/Client/ThirdParty/fpm/include/fpm/math.hpp +++ b/Client/ThirdParty/fpm/include/fpm/math.hpp @@ -538,7 +538,7 @@ fixed sin(fixed x) noexcept } const Fixed x2 = x*x; - return sign * x * (Fixed::pi() - x2*(Fixed::two_pi() - 5 - x2*(Fixed::pi() - 3)))/2; + return sign * x * (Fixed::pi() - x2*(Fixed::two_pi() - 5 - x2*(Fixed::pi() - 3)))/2.f; } template -- cgit v1.1-26-g67d0