[Gmp-commit] /var/hg/gmp: Fix LONG_MIN / mpz_class(-1)
mercurial at gmplib.org
mercurial at gmplib.org
Sun Nov 1 11:24:28 CET 2026
details: /var/hg/gmp/rev/722f5c638d3a
changeset: 18594:722f5c638d3a
user: Marc Glisse <marc.glisse at inria.fr>
date: Sun Nov 01 11:24:25 2026 +0100
description:
Fix LONG_MIN / mpz_class(-1)
diffstat:
ChangeLog | 6 ++++++
gmpxx.h | 18 ++++++++++++++++--
tests/cxx/t-ops2z.cc | 2 ++
3 files changed, 24 insertions(+), 2 deletions(-)
diffs (60 lines):
diff -r 19e57d407ade -r 722f5c638d3a ChangeLog
--- a/ChangeLog Mon Oct 26 13:09:17 2026 +0100
+++ b/ChangeLog Sun Nov 01 11:24:25 2026 +0100
@@ -1,3 +1,9 @@
+2026-11-01 Marc Glisse <marc.glisse at inria.fr>
+
+ * gmpxx.h (__gmp_binary_divides, __gmp_binary_modulus): Fix LONG_MIN /
+ mpz_class(-1).
+ * tests/cxx/t-ops2z.cc: Test it.
+
2026-10-26 Jeff Bailey <jbailey at raspberryginger.com>
* gmp-h.in (_GMP_H_HAVE_FILE): Test also _LLVM_LIBC_STDIO_H (for
diff -r 19e57d407ade -r 722f5c638d3a gmpxx.h
--- a/gmpxx.h Mon Oct 26 13:09:17 2026 +0100
+++ b/gmpxx.h Sun Nov 01 11:24:25 2026 +0100
@@ -671,7 +671,17 @@
static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
{
if (mpz_fits_slong_p(w))
- mpz_set_si(z, l / mpz_get_si(w));
+ {
+ signed long divisor = mpz_get_si(w);
+ // LONG_MIN / -1 is not representable as a signed long.
+ if (divisor == -1)
+ {
+ mpz_set_si(z, l);
+ mpz_neg(z, z);
+ }
+ else
+ mpz_set_si(z, l / divisor);
+ }
else
{
/* if w is bigger than a long then the quotient must be zero, unless
@@ -825,7 +835,11 @@
static void eval(mpz_ptr z, signed long int l, mpz_srcptr w)
{
if (mpz_fits_slong_p(w))
- mpz_set_si(z, l % mpz_get_si(w));
+ {
+ signed long divisor = mpz_get_si(w);
+ // LONG_MIN % -1 is undefined in C++ even though the result is zero.
+ mpz_set_si(z, divisor == -1 ? 0 : l % divisor);
+ }
else
{
/* if w is bigger than a long then the remainder is l unchanged,
diff -r 19e57d407ade -r 722f5c638d3a tests/cxx/t-ops2z.cc
--- a/tests/cxx/t-ops2z.cc Mon Oct 26 13:09:17 2026 +0100
+++ b/tests/cxx/t-ops2z.cc Sun Nov 01 11:24:25 2026 +0100
@@ -36,6 +36,8 @@
CHECK_ALL_SIGNS(mpz_class,17,2,%);
CHECK(unsigned long,mpz_class,5,-2,/);
CHECK(unsigned long,mpz_class,5,-2,%);
+ ASSERT_ALWAYS(LONG_MIN/mpz_class(-1)+LONG_MIN==0);
+ ASSERT_ALWAYS(LONG_MIN%mpz_class(-1)==0);
ASSERT_ALWAYS(7ul/mpz_class(1e35)==0);
ASSERT_ALWAYS(7ul%mpz_class(1e35)==7);
ASSERT_ALWAYS(7ul/mpz_class(-1e35)==0);
More information about the gmp-commit
mailing list