From 2820006caa88a1c7cffca2a7e5910611e30b025f Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Fri, 4 Oct 2024 14:45:49 -0400 Subject: [PATCH 1/4] Add fast type literals --- include/boost/decimal/literals.hpp | 122 ++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 4 deletions(-) diff --git a/include/boost/decimal/literals.hpp b/include/boost/decimal/literals.hpp index 150198546..73d55540f 100644 --- a/include/boost/decimal/literals.hpp +++ b/include/boost/decimal/literals.hpp @@ -34,17 +34,17 @@ BOOST_DECIMAL_EXPORT constexpr auto operator "" _df(const char* str) -> decimal return d; } -BOOST_DECIMAL_EXPORT constexpr auto operator "" _DF(const char* str, std::size_t) -> decimal32 +BOOST_DECIMAL_EXPORT constexpr auto operator "" _DF(const char* str, std::size_t len) -> decimal32 { decimal32 d; - from_chars(str, str + detail::strlen(str), d); + from_chars(str, str + len, d); return d; } -BOOST_DECIMAL_EXPORT constexpr auto operator "" _df(const char* str, std::size_t) -> decimal32 +BOOST_DECIMAL_EXPORT constexpr auto operator "" _df(const char* str, std::size_t len) -> decimal32 { decimal32 d; - from_chars(str, str + detail::strlen(str), d); + from_chars(str, str + len, d); return d; } @@ -58,6 +58,44 @@ BOOST_DECIMAL_EXPORT constexpr auto operator "" _df(unsigned long long v) -> de return decimal32{v}; } +BOOST_DECIMAL_EXPORT constexpr auto operator "" _DFF(const char* str) -> decimal32_fast +{ + decimal32_fast d; + from_chars(str, str + detail::strlen(str), d); + return d; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _dff(const char* str) -> decimal32_fast +{ + decimal32_fast d; + from_chars(str, str + detail::strlen(str), d); + return d; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _DFF(const char* str, std::size_t len) -> decimal32_fast +{ + decimal32_fast d; + from_chars(str, str + len, d); + return d; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _dff(const char* str, std::size_t len) -> decimal32_fast +{ + decimal32_fast d; + from_chars(str, str + len, d); + return d; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _DFF(unsigned long long v) -> decimal32_fast +{ + return decimal32_fast{v}; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _dff(unsigned long long v) -> decimal32_fast +{ + return decimal32_fast{v}; +} + BOOST_DECIMAL_EXPORT constexpr auto operator "" _DD(const char* str) -> decimal64 { decimal64 d; @@ -96,6 +134,44 @@ BOOST_DECIMAL_EXPORT constexpr auto operator "" _dd(unsigned long long v) -> de return decimal64{v}; } +BOOST_DECIMAL_EXPORT constexpr auto operator "" _DDF(const char* str) -> decimal64_fast +{ + decimal64_fast d; + from_chars(str, str + detail::strlen(str), d); + return d; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _ddf(const char* str) -> decimal64_fast +{ + decimal64_fast d; + from_chars(str, str + detail::strlen(str), d); + return d; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _DDF(const char* str, std::size_t len) -> decimal64_fast +{ + decimal64_fast d; + from_chars(str, str + len, d); + return d; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _ddf(const char* str, std::size_t len) -> decimal64_fast +{ + decimal64_fast d; + from_chars(str, str + len, d); + return d; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _DDF(unsigned long long v) -> decimal64_fast +{ + return decimal64_fast{v}; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _ddf(unsigned long long v) -> decimal64_fast +{ + return decimal64_fast{v}; +} + BOOST_DECIMAL_EXPORT constexpr auto operator "" _DL(const char* str) -> decimal128 { decimal128 d; @@ -134,6 +210,44 @@ BOOST_DECIMAL_EXPORT constexpr auto operator "" _dl(unsigned long long v) -> de return decimal128{v}; } +BOOST_DECIMAL_EXPORT constexpr auto operator "" _DLF(const char* str) -> decimal128_fast +{ + decimal128_fast d; + from_chars(str, str + detail::strlen(str), d); + return d; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _dlf(const char* str) -> decimal128_fast +{ + decimal128_fast d; + from_chars(str, str + detail::strlen(str), d); + return d; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _DLF(const char* str, std::size_t len) -> decimal128_fast +{ + decimal128_fast d; + from_chars(str, str + len, d); + return d; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _dlf(const char* str, std::size_t len) -> decimal128_fast +{ + decimal128_fast d; + from_chars(str, str + len, d); + return d; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _DLF(unsigned long long v) -> decimal128_fast +{ + return decimal128_fast{v}; +} + +BOOST_DECIMAL_EXPORT constexpr auto operator "" _dlf(unsigned long long v) -> decimal128_fast +{ + return decimal128_fast{v}; +} + } // namespace decimal } // namespace boost From 60eb9a4a21fab74bfdf01d6088fbe6aa508cdf54 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Fri, 4 Oct 2024 14:45:57 -0400 Subject: [PATCH 2/4] Add testing of fast type literals --- test/test_literals.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/test/test_literals.cpp b/test/test_literals.cpp index de47f36be..e8edc200f 100644 --- a/test/test_literals.cpp +++ b/test/test_literals.cpp @@ -26,6 +26,23 @@ void test_decimal32_literals() BOOST_TEST(isinf(5e300_df)); } +void test_decimal32_fast_literals() +{ + BOOST_TEST_EQ(decimal32_fast(0), 0_DFF); + BOOST_TEST_EQ(decimal32_fast(3), 3_DFF); + BOOST_TEST_EQ(decimal32_fast(3.1), 3.1_DFF); + BOOST_TEST_EQ(decimal32_fast(3, 1), 3e1_DFF); + BOOST_TEST(isinf(5e100_DFF)); + BOOST_TEST(isinf(5e300_DFF)); + + BOOST_TEST_EQ(decimal32_fast(0), 0_dff); + BOOST_TEST_EQ(decimal32_fast(3), 3_dff); + BOOST_TEST_EQ(decimal32_fast(3.1), 3.1_dff); + BOOST_TEST_EQ(decimal32_fast(3, 1), 3e1_dff); + BOOST_TEST(isinf(5e100_dff)); + BOOST_TEST(isinf(5e300_dff)); +} + void test_decimal64_literals() { BOOST_TEST_EQ(decimal64(0), 0_DD); @@ -47,6 +64,27 @@ void test_decimal64_literals() #endif } +void test_decimal64_fast_literals() +{ + BOOST_TEST_EQ(decimal64_fast(0), 0_DDF); + BOOST_TEST_EQ(decimal64_fast(3), 3_DDF); + BOOST_TEST_EQ(decimal64_fast(3.1), 3.1_DDF); + BOOST_TEST_EQ(decimal64_fast(3, 1), 3e1_DDF); + + BOOST_TEST_EQ(decimal64_fast(0), 0_ddf); + BOOST_TEST_EQ(decimal64_fast(3), 3_ddf); + BOOST_TEST_EQ(decimal64_fast(3.1), 3.1_ddf); + BOOST_TEST_EQ(decimal64_fast(3, 1), 3e1_ddf); + + // 64-bit long double warn of overflow + #if !(LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024) + BOOST_TEST(isinf(5e1000_ddf)); + BOOST_TEST(isinf(5e3000_ddf)); + BOOST_TEST(isinf(5e1000_DDF)); + BOOST_TEST(isinf(5e3000_DDF)); + #endif +} + void test_decimal128_literals() { BOOST_TEST_EQ(decimal128(0), 0_DL); @@ -60,11 +98,28 @@ void test_decimal128_literals() BOOST_TEST_EQ(decimal128(3, 1), 3e1_dl); } +void test_decimal128_fast_literals() +{ + BOOST_TEST_EQ(decimal128_fast(0), 0_DLF); + BOOST_TEST_EQ(decimal128_fast(3), 3_DLF); + BOOST_TEST_EQ(decimal128_fast(3.1), 3.1_DLF); + BOOST_TEST_EQ(decimal128_fast(3, 1), 3e1_DLF); + + BOOST_TEST_EQ(decimal128_fast(0), 0_dlf); + BOOST_TEST_EQ(decimal128_fast(3), 3_dlf); + BOOST_TEST_EQ(decimal128_fast(3.1), 3.1_dlf); + BOOST_TEST_EQ(decimal128_fast(3, 1), 3e1_dlf); +} + int main() { test_decimal32_literals(); test_decimal64_literals(); test_decimal128_literals(); + test_decimal32_fast_literals(); + test_decimal64_fast_literals(); + test_decimal128_fast_literals(); + return boost::report_errors(); } From b44ee5f00e7819787a09f57b88ddb4f268cf2d1a Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Fri, 4 Oct 2024 14:46:06 -0400 Subject: [PATCH 3/4] Add documentation of fast type literals --- doc/decimal/literals.adoc | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/doc/decimal/literals.adoc b/doc/decimal/literals.adoc index 5dd6fb451..35fba1c02 100644 --- a/doc/decimal/literals.adoc +++ b/doc/decimal/literals.adoc @@ -19,7 +19,7 @@ constexpr auto operator "" _DF(const char* str) -> decimal32 constexpr auto operator "" _df(const char* str) -> decimal32 constexpr auto operator "" _DF(unsigned long long v) -> decimal32 -constexpr auto operator "" _dF(unsigned long long v) -> decimal32 +constexpr auto operator "" _df(unsigned long long v) -> decimal32 constexpr auto operator "" _DD(const char* str) -> decimal64 constexpr auto operator "" _dd(const char* str) -> decimal64 @@ -33,6 +33,26 @@ constexpr auto operator "" _dl(const char* str) -> decimal128 constexpr auto operator "" _DL(unsigned long long v) -> decimal128 constexpr auto operator "" _dl(unsigned long long v) -> decimal128 +// ----- Fast Type Literals ----- + +constexpr auto operator "" _DFF(const char* str) -> decimal32_fast +constexpr auto operator "" _dff(const char* str) -> decimal32_fast + +constexpr auto operator "" _DFF(unsigned long long v) -> decimal32_fast +constexpr auto operator "" _dff(unsigned long long v) -> decimal32_fast + +constexpr auto operator "" _DDF(const char* str) -> decimal64_fast +constexpr auto operator "" _ddf(const char* str) -> decimal64_fast + +constexpr auto operator "" _DDF(unsigned long long v) -> decimal64_fast +constexpr auto operator "" _ddf(unsigned long long v) -> decimal64_fast + +constexpr auto operator "" _DLF(const char* str) -> decimal128_fast +constexpr auto operator "" _dlf(const char* str) -> decimal128_fast + +constexpr auto operator "" _DLF(unsigned long long v) -> decimal128_fast +constexpr auto operator "" _dlf(unsigned long long v) -> decimal128_fast + } //namespace decimal } //namespace boost ---- From 71ed9997a6bb16d71a65ee2aa556d1a497aeef87 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Fri, 4 Oct 2024 15:43:23 -0400 Subject: [PATCH 4/4] Fix exp range of dec32_fast --- include/boost/decimal/decimal32_fast.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/decimal/decimal32_fast.hpp b/include/boost/decimal/decimal32_fast.hpp index b650ff2d7..b9da53790 100644 --- a/include/boost/decimal/decimal32_fast.hpp +++ b/include/boost/decimal/decimal32_fast.hpp @@ -385,7 +385,7 @@ constexpr decimal32_fast::decimal32_fast(T1 coeff, T2 exp, bool sign) noexcept auto biased_exp {static_cast(exp + detail::bias)}; // Decimal32 exponent holds 8 bits - if (biased_exp > UINT32_C(0xFF)) + if (biased_exp > detail::max_biased_exp_v) { significand_ = detail::d32_fast_inf; }