From 91eaf40b1ff7f2b2fd0ecf4572de524c67d3d7d6 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 29 Mar 2016 20:04:49 -0600 Subject: [PATCH] fix `modulo` and `remainder` related to most negative fixnum Robby noticed the bug while looking for undefined behavior. --- pkgs/racket-test-core/tests/racket/number.rktl | 9 +++++++++ racket/src/racket/src/numarith.c | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/number.rktl b/pkgs/racket-test-core/tests/racket/number.rktl index f104598def..e6e39b3baf 100644 --- a/pkgs/racket-test-core/tests/racket/number.rktl +++ b/pkgs/racket-test-core/tests/racket/number.rktl @@ -1110,6 +1110,15 @@ (err/rt-test (remainder 2 1+2i)) (err/rt-test (modulo 2 1+2i)) +(test (- (expt 2 65) (expt 2 62)) + modulo (- (+ (expt 2 62) (expt 2 65))) (expt 2 65)) +(test (- (expt 2 33) (expt 2 30)) + modulo (- (+ (expt 2 30) (expt 2 33))) (expt 2 33)) +(test (- (expt 2 62)) + remainder (- (+ (expt 2 62) (expt 2 65))) (expt 2 65)) +(test (- (expt 2 30)) + remainder (- (+ (expt 2 30) (expt 2 33))) (expt 2 33)) + (test 10 bitwise-ior 10) (test 10 bitwise-and 10) (test 10 bitwise-xor 10) diff --git a/racket/src/racket/src/numarith.c b/racket/src/racket/src/numarith.c index a15b76fc2b..fd3b7e6f33 100644 --- a/racket/src/racket/src/numarith.c +++ b/racket/src/racket/src/numarith.c @@ -1094,7 +1094,7 @@ rem_mod (int argc, Scheme_Object *argv[], char *name, int first_sign) /* Easier if we can assume 'r' is positive: */ if (SCHEME_INTP(r)) { if (SCHEME_INT_VAL(r) < 0) - r = scheme_make_integer(-SCHEME_INT_VAL(r)); + r = scheme_make_integer_value(-SCHEME_INT_VAL(r)); } else if (!SCHEME_BIGPOS(r)) r = scheme_bignum_negate(r); @@ -1118,9 +1118,9 @@ rem_mod (int argc, Scheme_Object *argv[], char *name, int first_sign) if (negate) { if (SCHEME_INTP(r)) - r = scheme_make_integer(-SCHEME_INT_VAL(r)); + r = scheme_make_integer_value(-SCHEME_INT_VAL(r)); else - r = scheme_bignum_negate(r); + r = scheme_bignum_normalize(scheme_bignum_negate(r)); } }