From 3e787bd89d0dc7cd99825b9b271604c31128ace5 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 17 Jun 2026 12:56:05 -0400 Subject: [PATCH 1/4] Fix missing copyright info --- test/github_issue_1384.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/github_issue_1384.cpp b/test/github_issue_1384.cpp index 56377d2da..17b2998de 100644 --- a/test/github_issue_1384.cpp +++ b/test/github_issue_1384.cpp @@ -1,3 +1,8 @@ +// Copyright 2026 Chris Kormanyos +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/boostorg/decimal/issues/1384 #include From f6a4b56b1f55a4e1a3db78d2d46c5e056ce84324 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 17 Jun 2026 13:02:02 -0400 Subject: [PATCH 2/4] Add reproducer derived from issue --- test/Jamfile | 1 + test/github_issue_1398.cpp | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 test/github_issue_1398.cpp diff --git a/test/Jamfile b/test/Jamfile index 903d91d9f..7c277bb70 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -96,6 +96,7 @@ run github_issue_1361.cpp ; run github_issue_1378.cpp ; run github_issue_1383.cpp ; run github_issue_1384.cpp ; +run github_issue_1398.cpp ; run link_1.cpp link_2.cpp link_3.cpp ; run quick.cpp ; diff --git a/test/github_issue_1398.cpp b/test/github_issue_1398.cpp new file mode 100644 index 000000000..0197247bd --- /dev/null +++ b/test/github_issue_1398.cpp @@ -0,0 +1,37 @@ +// Copyright 2026 Chris Kormanyos +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/boostorg/decimal/issues/1398 + +#include +#include +#include + +template +void test() +{ + using namespace boost::decimal; + + constexpr auto builtin_neg_inf = -std::numeric_limits::infinity(); + + const auto d32 = decimal32_t(builtin_neg_inf); + BOOST_TEST(isinf(d32)); + BOOST_TEST(d32 < 0); + + const auto d64 = decimal64_t(builtin_neg_inf); + BOOST_TEST(isinf(d64)); + BOOST_TEST(d64 < 0); + + const auto d128 = decimal128_t(builtin_neg_inf); + BOOST_TEST(isinf(d128)); + BOOST_TEST(d128 < 0); +} + +int main() +{ + test(); + test(); + + return boost::report_errors(); +} From b4c29bcbea0fe8a526ae20559ecf92aa377b4520 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 17 Jun 2026 13:04:17 -0400 Subject: [PATCH 3/4] Improve test --- test/github_issue_1398.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/test/github_issue_1398.cpp b/test/github_issue_1398.cpp index 0197247bd..10f854e81 100644 --- a/test/github_issue_1398.cpp +++ b/test/github_issue_1398.cpp @@ -8,24 +8,29 @@ #include #include -template -void test() +template +void test_driver() { using namespace boost::decimal; constexpr auto builtin_neg_inf = -std::numeric_limits::infinity(); - const auto d32 = decimal32_t(builtin_neg_inf); - BOOST_TEST(isinf(d32)); - BOOST_TEST(d32 < 0); + const auto val = U(builtin_neg_inf); + BOOST_TEST(isinf(val)); + BOOST_TEST(val < 0); +} - const auto d64 = decimal64_t(builtin_neg_inf); - BOOST_TEST(isinf(d64)); - BOOST_TEST(d64 < 0); +template +void test() +{ + using namespace boost::decimal; - const auto d128 = decimal128_t(builtin_neg_inf); - BOOST_TEST(isinf(d128)); - BOOST_TEST(d128 < 0); + test_driver(); + test_driver(); + test_driver(); + test_driver(); + test_driver(); + test_driver(); } int main() From 0d99c84e619606ddedd046b91dd66eeb56dff1e7 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 17 Jun 2026 13:10:44 -0400 Subject: [PATCH 4/4] Fix construction from negative inf binary floats --- include/boost/decimal/decimal128_t.hpp | 6 +++++- include/boost/decimal/decimal32_t.hpp | 6 +++++- include/boost/decimal/decimal64_t.hpp | 6 +++++- include/boost/decimal/decimal_fast128_t.hpp | 7 ++++++- include/boost/decimal/decimal_fast32_t.hpp | 7 ++++++- include/boost/decimal/decimal_fast64_t.hpp | 7 ++++++- 6 files changed, 33 insertions(+), 6 deletions(-) diff --git a/include/boost/decimal/decimal128_t.hpp b/include/boost/decimal/decimal128_t.hpp index d598ad945..adc3ec3fa 100644 --- a/include/boost/decimal/decimal128_t.hpp +++ b/include/boost/decimal/decimal128_t.hpp @@ -1052,10 +1052,14 @@ BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t::decimal128_t(const Float val) noexce { *this = from_bits(detail::d128_nan_mask); } - else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) + else if (val == std::numeric_limits::infinity()) { *this = from_bits(detail::d128_inf_mask); } + else if (val == -std::numeric_limits::infinity()) + { + *this = -from_bits(detail::d128_inf_mask); + } else #endif { diff --git a/include/boost/decimal/decimal32_t.hpp b/include/boost/decimal/decimal32_t.hpp index 18dedecb1..89196ca3f 100644 --- a/include/boost/decimal/decimal32_t.hpp +++ b/include/boost/decimal/decimal32_t.hpp @@ -1801,10 +1801,14 @@ BOOST_DECIMAL_CXX20_CONSTEXPR decimal32_t::decimal32_t(const Float val) noexcept { *this = boost::decimal::from_bits(boost::decimal::detail::d32_nan_mask); } - else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) + else if (val == std::numeric_limits::infinity()) { *this = boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask); } + else if (val == -std::numeric_limits::infinity()) + { + *this = -boost::decimal::from_bits(boost::decimal::detail::d32_inf_mask); + } else #endif { diff --git a/include/boost/decimal/decimal64_t.hpp b/include/boost/decimal/decimal64_t.hpp index 51f2d0ca8..728321136 100644 --- a/include/boost/decimal/decimal64_t.hpp +++ b/include/boost/decimal/decimal64_t.hpp @@ -1006,10 +1006,14 @@ BOOST_DECIMAL_CXX20_CONSTEXPR decimal64_t::decimal64_t(const Float val) noexcept { *this = from_bits(detail::d64_nan_mask); } - else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) + else if (val == std::numeric_limits::infinity()) { *this = from_bits(detail::d64_inf_mask); } + else if (val == -std::numeric_limits::infinity()) + { + *this = -from_bits(detail::d64_inf_mask); + } else #endif { diff --git a/include/boost/decimal/decimal_fast128_t.hpp b/include/boost/decimal/decimal_fast128_t.hpp index cb5f2b035..052282b18 100644 --- a/include/boost/decimal/decimal_fast128_t.hpp +++ b/include/boost/decimal/decimal_fast128_t.hpp @@ -619,10 +619,15 @@ BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast128_t::decimal_fast128_t(const Float v { significand_ = detail::d128_fast_qnan; } - else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) + else if (val == std::numeric_limits::infinity()) { significand_ = detail::d128_fast_inf; } + else if (val == -std::numeric_limits::infinity()) + { + significand_ = detail::d128_fast_inf; + sign_ = true; + } else #endif { diff --git a/include/boost/decimal/decimal_fast32_t.hpp b/include/boost/decimal/decimal_fast32_t.hpp index 7493a5790..2c34d7180 100644 --- a/include/boost/decimal/decimal_fast32_t.hpp +++ b/include/boost/decimal/decimal_fast32_t.hpp @@ -724,10 +724,15 @@ BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast32_t::decimal_fast32_t(const Float val { significand_ = detail::d32_fast_qnan; } - else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) + else if (val == std::numeric_limits::infinity()) { significand_ = detail::d32_fast_inf; } + else if (val == -std::numeric_limits::infinity()) + { + significand_ = detail::d32_fast_inf; + sign_ = true; + } else #endif { diff --git a/include/boost/decimal/decimal_fast64_t.hpp b/include/boost/decimal/decimal_fast64_t.hpp index b282e8c8d..6f4046098 100644 --- a/include/boost/decimal/decimal_fast64_t.hpp +++ b/include/boost/decimal/decimal_fast64_t.hpp @@ -621,10 +621,15 @@ BOOST_DECIMAL_CXX20_CONSTEXPR decimal_fast64_t::decimal_fast64_t(const Float val { significand_ = detail::d64_fast_qnan; } - else if (val == std::numeric_limits::infinity() || val == -std::numeric_limits::infinity()) + else if (val == std::numeric_limits::infinity()) { significand_ = detail::d64_fast_inf; } + else if (val == -std::numeric_limits::infinity()) + { + significand_ = detail::d64_fast_inf; + sign_ = true; + } else #endif {