fix division and modulo giving incorrect results
parent
39779666a3
commit
8b8741d262
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue