fix division and modulo giving incorrect results

cvs
Slava Pestov 2004-08-27 03:05:48 +00:00
parent 39779666a3
commit 8b8741d262
5 changed files with 13 additions and 28 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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