From 0c6fff035b02794b0ff019b21fd72c130d19ee8c Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 22 Jan 2026 11:54:36 -0500 Subject: [PATCH 1/4] Add reproducer test --- test/random_decimal64_math.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/random_decimal64_math.cpp b/test/random_decimal64_math.cpp index f8d8232cc..96ba55f08 100644 --- a/test/random_decimal64_math.cpp +++ b/test/random_decimal64_math.cpp @@ -611,6 +611,8 @@ int main() spot_mixed_division(4930, -24419); + BOOST_TEST_EQ(decimal64_t{"Inf"} / decimal64_t{-1000}, -std::numeric_limits::infinity()); + return boost::report_errors(); } From 3cfa5d21c0b0b40f1a218ae53dd297f1c5a1a26e Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 22 Jan 2026 11:54:50 -0500 Subject: [PATCH 2/4] Fix decimal64 non-finite division handling --- include/boost/decimal/decimal64_t.hpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/include/boost/decimal/decimal64_t.hpp b/include/boost/decimal/decimal64_t.hpp index 8c7fb6e99..43ded8ed1 100644 --- a/include/boost/decimal/decimal64_t.hpp +++ b/include/boost/decimal/decimal64_t.hpp @@ -1576,8 +1576,16 @@ constexpr auto d64_div_impl(const decimal64_t lhs, const decimal64_t rhs, decima case FP_INFINITE: if (lhs_fp == FP_INFINITE) { - q = nan; - r = nan; + if (rhs_fp == FP_INFINITE) + { + q = nan; + r = nan; + } + else + { + q = sign ? -inf : inf; + r = zero; + } } else { @@ -1604,7 +1612,7 @@ constexpr auto d64_div_impl(const decimal64_t lhs, const decimal64_t rhs, decima switch (rhs_fp) { case FP_ZERO: - q = inf; + q = sign ? -inf : inf; r = zero; return; case FP_INFINITE: From 8a1c191fc932e615177a653b488325de8c00ebae Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 22 Jan 2026 12:51:45 -0500 Subject: [PATCH 3/4] Add unified test set --- test/Jamfile | 1 + test/github_issue_1312.cpp | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 test/github_issue_1312.cpp diff --git a/test/Jamfile b/test/Jamfile index e439f7ebf..bee61767e 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -87,6 +87,7 @@ run github_issue_1299.cpp ; run github_issue_1302.cpp ; run github_issue_1304.cpp ; run github_issue_1306.cpp ; +run github_issue_1312.cpp ; run link_1.cpp link_2.cpp link_3.cpp ; run quick.cpp ; diff --git a/test/github_issue_1312.cpp b/test/github_issue_1312.cpp new file mode 100644 index 000000000..e70084ea9 --- /dev/null +++ b/test/github_issue_1312.cpp @@ -0,0 +1,37 @@ +// Copyright 2026 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// See: https://github.com/cppalliance/decimal/issues/1312 + +#include +#include +#include + +using namespace boost::decimal; + +template +void test() +{ + constexpr T inf {std::numeric_limits::infinity()}; + + BOOST_TEST(isnan(inf / -inf)); + BOOST_TEST_EQ(inf / -1000, -inf); + BOOST_TEST_EQ(inf / -T{1000}, -inf); + BOOST_TEST_EQ(inf / 0, inf); + BOOST_TEST_EQ(inf / T{0}, inf); + BOOST_TEST_EQ(0 / inf, T{0}); +} + +int main() +{ + test(); + test(); + test(); + + test(); + test(); + test(); + + return boost::report_errors(); +} From fc8fce141796e93a49da54149914381ba9c189e5 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Thu, 22 Jan 2026 12:51:55 -0500 Subject: [PATCH 4/4] Fix integral division logic --- include/boost/decimal/decimal128_t.hpp | 2 +- include/boost/decimal/decimal32_t.hpp | 2 +- include/boost/decimal/decimal64_t.hpp | 16 ++++------------ include/boost/decimal/decimal_fast128_t.hpp | 2 +- include/boost/decimal/decimal_fast32_t.hpp | 2 +- include/boost/decimal/decimal_fast64_t.hpp | 2 +- 6 files changed, 9 insertions(+), 17 deletions(-) diff --git a/include/boost/decimal/decimal128_t.hpp b/include/boost/decimal/decimal128_t.hpp index 4daf10730..b6b8bd9b4 100644 --- a/include/boost/decimal/decimal128_t.hpp +++ b/include/boost/decimal/decimal128_t.hpp @@ -1899,7 +1899,7 @@ constexpr auto operator/(const decimal128_t lhs, const Integer rhs) noexcept case FP_NAN: return issignaling(lhs) ? nan_conversion(lhs) : lhs; case FP_INFINITE: - return lhs; + return sign ? -lhs : lhs; case FP_ZERO: return sign ? -zero : zero; default: diff --git a/include/boost/decimal/decimal32_t.hpp b/include/boost/decimal/decimal32_t.hpp index 735ecc0b7..69281ceef 100644 --- a/include/boost/decimal/decimal32_t.hpp +++ b/include/boost/decimal/decimal32_t.hpp @@ -2043,7 +2043,7 @@ constexpr auto operator/(const decimal32_t lhs, Integer rhs) noexcept case FP_NAN: return issignaling(lhs) ? nan_conversion(lhs) : lhs; case FP_INFINITE: - return lhs; + return sign ? -lhs : lhs; case FP_ZERO: return sign ? -zero : zero; default: diff --git a/include/boost/decimal/decimal64_t.hpp b/include/boost/decimal/decimal64_t.hpp index 43ded8ed1..7efa1c843 100644 --- a/include/boost/decimal/decimal64_t.hpp +++ b/include/boost/decimal/decimal64_t.hpp @@ -1574,18 +1574,10 @@ constexpr auto d64_div_impl(const decimal64_t lhs, const decimal64_t rhs, decima switch (lhs_fp) { case FP_INFINITE: - if (lhs_fp == FP_INFINITE) + if (rhs_fp == FP_INFINITE) { - if (rhs_fp == FP_INFINITE) - { - q = nan; - r = nan; - } - else - { - q = sign ? -inf : inf; - r = zero; - } + q = nan; + r = nan; } else { @@ -1909,7 +1901,7 @@ constexpr auto operator/(const decimal64_t lhs, const Integer rhs) noexcept case FP_NAN: return issignaling(lhs) ? nan_conversion(lhs) : lhs; case FP_INFINITE: - return lhs; + return sign ? -lhs : lhs; case FP_ZERO: return sign ? -zero : zero; default: diff --git a/include/boost/decimal/decimal_fast128_t.hpp b/include/boost/decimal/decimal_fast128_t.hpp index a7d247129..ee4e04817 100644 --- a/include/boost/decimal/decimal_fast128_t.hpp +++ b/include/boost/decimal/decimal_fast128_t.hpp @@ -1350,7 +1350,7 @@ constexpr auto operator/(const decimal_fast128_t& lhs, const Integer rhs) noexce case FP_NAN: return issignaling(lhs) ? nan_conversion(lhs) : lhs;; case FP_INFINITE: - return lhs; + return sign ? -lhs : lhs; case FP_ZERO: return sign ? -zero : zero; default: diff --git a/include/boost/decimal/decimal_fast32_t.hpp b/include/boost/decimal/decimal_fast32_t.hpp index 9d431766c..661a0dc38 100644 --- a/include/boost/decimal/decimal_fast32_t.hpp +++ b/include/boost/decimal/decimal_fast32_t.hpp @@ -1335,7 +1335,7 @@ constexpr auto operator/(const decimal_fast32_t lhs, const Integer rhs) noexcept case FP_NAN: return issignaling(lhs) ? nan_conversion(lhs) : lhs; case FP_INFINITE: - return lhs; + return sign ? -lhs : lhs; case FP_ZERO: return sign ? -zero : zero; default: diff --git a/include/boost/decimal/decimal_fast64_t.hpp b/include/boost/decimal/decimal_fast64_t.hpp index 4e258bd6d..504742f0e 100644 --- a/include/boost/decimal/decimal_fast64_t.hpp +++ b/include/boost/decimal/decimal_fast64_t.hpp @@ -1480,7 +1480,7 @@ constexpr auto operator/(const decimal_fast64_t lhs, const Integer rhs) noexcept case FP_NAN: return issignaling(lhs) ? nan_conversion(lhs) : lhs;; case FP_INFINITE: - return lhs; + return sign ? -lhs : lhs; case FP_ZERO: return sign ? -zero : zero; default: