From 3111e690846bd95b8d03e1206cab2208a135e121 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Thu, 21 Feb 2013 13:05:41 +0000 Subject: [PATCH] Fix sign of division in cpp_int when the values are small enough to fit in a double_limb_type. Add test cases for above. Fixes #8126. [SVN r83060] --- doc/multiprecision.qbk | 2 ++ .../boost/multiprecision/cpp_int/divide.hpp | 6 ++++++ test/test_cpp_int.cpp | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/doc/multiprecision.qbk b/doc/multiprecision.qbk index b8806959..cb68d280 100644 --- a/doc/multiprecision.qbk +++ b/doc/multiprecision.qbk @@ -3617,6 +3617,8 @@ Windows Vista machine. * [*Breaking change] renamed `rational_adapter` to `rational_adaptor`. * Add support for [mpfi]. * Add logged_adaptor. +* Fix bug in integer division that results in incorrect sign of `cpp_int` when both arguments are small enough +to fit in a `double_limb_type`. See [@https://svn.boost.org/trac/boost/ticket/8126 8126]. [h4 1.53] diff --git a/include/boost/multiprecision/cpp_int/divide.hpp b/include/boost/multiprecision/cpp_int/divide.hpp index 793fe0d9..21c973d3 100644 --- a/include/boost/multiprecision/cpp_int/divide.hpp +++ b/include/boost/multiprecision/cpp_int/divide.hpp @@ -114,7 +114,10 @@ void divide_unsigned_helper( if(r_order == 0) { if(result) + { *result = px[0] / py[0]; + result->sign(x.sign() != y.sign()); + } r = px[0] % py[0]; return; } @@ -126,7 +129,10 @@ void divide_unsigned_helper( (static_cast(py[1]) << CppInt1::limb_bits) | py[0] : py[0]; if(result) + { *result = a / b; + result->sign(x.sign() != y.sign()); + } r = a % b; return; } diff --git a/test/test_cpp_int.cpp b/test/test_cpp_int.cpp index fee9686c..79e8cce7 100644 --- a/test/test_cpp_int.cpp +++ b/test/test_cpp_int.cpp @@ -470,6 +470,25 @@ struct tester } } + // + // Specific bug report tests come last: + // + // Bug https://svn.boost.org/trac/boost/ticket/8126: + test_type a("-4294967296"); + test_type b("4294967296"); + test_type c("-1"); + a = (a / b); + BOOST_CHECK_EQUAL(a, -1); + a = -4294967296; + a = (a / b) * c; + BOOST_CHECK_EQUAL(a, 1); + a = -23; + b = 23; + a = (a / b) * c; + BOOST_CHECK_EQUAL(a, 1); + a = -23; + a = (a / b) / c; + BOOST_CHECK_EQUAL(a, 1); } };