diff options
author | Alex Shinn <alexshinn@gmail.com> | 2024-02-22 16:32:20 +0900 |
---|---|---|
committer | Alex Shinn <alexshinn@gmail.com> | 2024-02-22 16:32:20 +0900 |
commit | 56ef426dfa8d0a19dc2f76d52f432b21af1c6286 (patch) | |
tree | 099155b5170192a3e97544276f3162ffc58ece26 | |
parent | 29dd1a3b81e297033f687cbbf2b51319856647f4 (diff) |
Catch division edge case of (/ fx-least -1).
Thanks for Jim Rees for reporting.
-rw-r--r-- | bignum.c | 3 | ||||
-rw-r--r-- | tests/r7rs-tests.scm | 7 | ||||
-rw-r--r-- | vm.c | 3 |
3 files changed, 13 insertions, 0 deletions
@@ -1762,6 +1762,9 @@ sexp sexp_quotient (sexp ctx, sexp a, sexp b) { break; case SEXP_NUM_FIX_FIX: r = sexp_fx_div(a, b); + if ((sexp_sint_t)a < 0 && (sexp_sint_t)b < 0 && (sexp_sint_t)r < 0) { + r = sexp_quotient(ctx, tmp=sexp_fixnum_to_bignum(ctx, a), b); + } break; case SEXP_NUM_FIX_BIG: r = SEXP_ZERO; diff --git a/tests/r7rs-tests.scm b/tests/r7rs-tests.scm index 32f74576..6596074d 100644 --- a/tests/r7rs-tests.scm +++ b/tests/r7rs-tests.scm @@ -904,6 +904,13 @@ (test 3/20 (/ 3 4 5)) (test 1/3 (/ 3)) +(test 1073741824 (/ -1073741824 -1)) +(test 1073741824 (quotient -1073741824 -1)) +(test 0 (remainder -1073741824 -1)) +(test 4611686018427387904 (/ -4611686018427387904 -1)) +(test 4611686018427387904 (quotient -4611686018427387904 -1)) +(test 0 (remainder -4611686018427387904 -1)) + (test 7 (abs -7)) (test 7 (abs 7)) @@ -1891,6 +1891,9 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) { if (tmp2 == SEXP_ZERO) sexp_raise("divide by zero", SEXP_NULL); _ARG1 = sexp_fx_div(tmp1, tmp2); + if ((sexp_sint_t)tmp1 < 0 && (sexp_sint_t)tmp2 < 0 && (sexp_sint_t)_ARG1 < 0) { + _ARG1 = sexp_quotient(ctx, tmp1=sexp_fixnum_to_bignum(ctx, tmp1), tmp2); + } } #if SEXP_USE_BIGNUMS else { |