From 8b8741d262500a5a2e768160bb199c4a977b566c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 27 Aug 2004 03:05:48 +0000 Subject: [PATCH] fix division and modulo giving incorrect results --- library/test/math/bignum.factor | 1 + native/bignum.c | 16 ++++------------ native/s48_bignum.c | 18 ++++++------------ native/s48_bignum.h | 2 -- native/s48_bignumint.h | 4 ++-- 5 files changed, 13 insertions(+), 28 deletions(-) diff --git a/library/test/math/bignum.factor b/library/test/math/bignum.factor index 1e17337b8e..28cf2fb1da 100644 --- a/library/test/math/bignum.factor +++ b/library/test/math/bignum.factor @@ -23,3 +23,4 @@ unit-test [ 1/268435456 ] [ -1 -268435456 >fixnum / ] unit-test [ 0 ] [ -1 -268435456 >fixnum /i ] unit-test [ 0 -1 ] [ -1 -268435456 >fixnum /mod ] unit-test +[ 14355 ] [ 1591517158873146351817850880000000 32769 mod ] unit-test diff --git a/native/bignum.c b/native/bignum.c index 7129ff861c..369e0dbe61 100644 --- a/native/bignum.c +++ b/native/bignum.c @@ -120,10 +120,7 @@ CELL divide_bignum(ARRAY* x, ARRAY* y) CELL divint_bignum(ARRAY* x, ARRAY* y) { - ARRAY* q = s48_bignum_quotient(x,y); - if(q == NULL) - raise(SIGFPE); - return tag_object(q); + return tag_object(s48_bignum_quotient(x,y)); } CELL divfloat_bignum(ARRAY* x, ARRAY* y) @@ -135,20 +132,15 @@ CELL divfloat_bignum(ARRAY* x, ARRAY* y) CELL divmod_bignum(ARRAY* x, ARRAY* y) { - ARRAY* q; - ARRAY* r; - if(s48_bignum_divide(x,y,&q,&r)) - raise(SIGFPE); + ARRAY *q, *r; + s48_bignum_divide(x,y,&q,&r); dpush(tag_object(q)); return tag_object(r); } CELL mod_bignum(ARRAY* x, ARRAY* y) { - ARRAY* r = s48_bignum_remainder(x,y); - if(r == NULL) - raise(SIGFPE); - return tag_object(r); + return tag_object(s48_bignum_remainder(x,y)); } CELL and_bignum(ARRAY* x, ARRAY* y) diff --git a/native/s48_bignum.c b/native/s48_bignum.c index 4f795a9315..656d18d333 100644 --- a/native/s48_bignum.c +++ b/native/s48_bignum.c @@ -177,12 +177,15 @@ s48_bignum_multiply(bignum_type x, bignum_type y) return (bignum_multiply_unsigned (x, y, negative_p)); } -int -bignum_divide(bignum_type numerator, bignum_type denominator, +void +s48_bignum_divide(bignum_type numerator, bignum_type denominator, bignum_type * quotient, bignum_type * remainder) { if (BIGNUM_ZERO_P (denominator)) - return (1); + { + raise(SIGFPE); + return; + } if (BIGNUM_ZERO_P (numerator)) { (*quotient) = (BIGNUM_MAYBE_COPY (numerator)); @@ -244,15 +247,6 @@ bignum_divide(bignum_type numerator, bignum_type denominator, } } } - return (0); -} - -int -s48_bignum_divide(bignum_type numerator, bignum_type denominator, - void* quotient, void * remainder) -{ - return bignum_divide(numerator, denominator, - (bignum_type *)quotient, (bignum_type *)remainder); } bignum_type diff --git a/native/s48_bignum.h b/native/s48_bignum.h index 416d012217..91fcb5bdd4 100644 --- a/native/s48_bignum.h +++ b/native/s48_bignum.h @@ -60,8 +60,6 @@ bignum_type s48_bignum_add(bignum_type, bignum_type); bignum_type s48_bignum_subtract(bignum_type, bignum_type); bignum_type s48_bignum_negate(bignum_type); bignum_type s48_bignum_multiply(bignum_type, bignum_type); -int s48_bignum_divide(bignum_type numerator, bignum_type denominator, - void * quotient, void * remainder); bignum_type s48_bignum_quotient(bignum_type, bignum_type); bignum_type s48_bignum_remainder(bignum_type, bignum_type); bignum_type s48_long_to_bignum(long); diff --git a/native/s48_bignumint.h b/native/s48_bignumint.h index 2d7f89dde2..4284782ca9 100644 --- a/native/s48_bignumint.h +++ b/native/s48_bignumint.h @@ -42,8 +42,8 @@ MIT in each case. */ definition is `CHAR_BIT', which is defined in the Ansi C header file "limits.h". */ -typedef CELL bignum_digit_type; -typedef CELL bignum_length_type; +typedef long bignum_digit_type; +typedef long bignum_length_type; /* BIGNUM_ALLOCATE allocates a (length + 1)-element array of `bignum_digit_type'; deallocation is the responsibility of the