++ bignums:\r
+\r
+- -1 is broken, add a test to verify this in the future\r
+- gcd is broken\r
+- bignum/ is broken\r
+- change shift< and shift> to ash\r
+- gcd is broken\r
+- cached 0/-1/1 should be cross compiled in image\r
+- bignum cross compiling\r
+- upgrading fixnums does not work\r
+- ash is inefficient: arg 2 is upgraded to bignum then back\r
+ to long\r
+- move some s48_ functions into bignum.c\r
+- remove unused functions\r
+\r
- add a socket timeout\r
- >lower, >upper for strings\r
- telnetd should use multitasking\r
( Bignums )
: 'bignum ( bignum -- tagged )
- #! Very bad!
- object-tag here-as >r
- bignum-type >header emit
- 4 emit ( capacity )
- 0 emit ( sign XXXX )
- 0 emit ( pad XXXX )
- ( bignum -- ) emit64 r> ;
+ 'fixnum ;
+! #! Very bad!
+! object-tag here-as >r
+! bignum-type >header emit
+! 1 emit ( capacity )
+! 0 emit ( sign XXXX )
+! ( bignum -- ) emit r> ;
( Special objects )
}
}
-BIGNUM* fixnum_to_bignum(CELL n)
+ARRAY* fixnum_to_bignum(CELL n)
{
- return bignum((BIGNUM_2)untag_fixnum_fast(n));
+ return s48_long_to_bignum(untag_fixnum_fast(n));
}
RATIO* fixnum_to_ratio(CELL n)
FIXNUM bignum_to_fixnum(CELL tagged)
{
- return (FIXNUM)(((BIGNUM*)UNTAG(tagged))->n);
+ return (FIXNUM)s48_bignum_to_long(
+ (ARRAY*)UNTAG(tagged));
}
RATIO* bignum_to_ratio(CELL n)
FLOAT* bignum_to_float(CELL tagged)
{
- return make_float((double)((BIGNUM*)UNTAG(tagged))->n);
+ return make_float(s48_bignum_to_double(
+ (ARRAY*)UNTAG(tagged)));
}
FLOAT* ratio_to_float(CELL tagged)
case FIXNUM_TYPE:
return tagged == 0;
case BIGNUM_TYPE:
- return ((BIGNUM*)UNTAG(tagged))->n == 0;
+ return BIGNUM_ZERO_P((ARRAY*)UNTAG(tagged));
case FLOAT_TYPE:
return ((FLOAT*)UNTAG(tagged))->n == 0.0;
case RATIO_TYPE:
#include "factor.h"
CELL upgraded_arithmetic_type(CELL type1, CELL type2);
-BIGNUM* fixnum_to_bignum(CELL n);
+ARRAY* fixnum_to_bignum(CELL n);
RATIO* fixnum_to_ratio(CELL n);
FLOAT* fixnum_to_float(CELL n);
FIXNUM bignum_to_fixnum(CELL tagged);
#define CELL_TO_INTEGER(result) \
FIXNUM _result = (result); \
- if(_result < FIXNUM_MIN || _result > FIXNUM_MAX) \
+ /* if(_result < FIXNUM_MIN || _result > FIXNUM_MAX) \
return tag_object(fixnum_to_bignum(_result)); \
else \
- return tag_fixnum(_result);
+ */return tag_fixnum(_result);
#define BIGNUM_2_TO_INTEGER(result) \
BIGNUM_2 _result = (result); \
- if(_result < FIXNUM_MIN || _result > FIXNUM_MAX) \
- return tag_object(bignum(_result)); \
+ /* if(_result < FIXNUM_MIN || _result > FIXNUM_MAX) \
+ return tag_object(s48_long_to_bignum(_result)); \
else \
- return tag_fixnum(_result);
+ */return tag_fixnum(_result);
#define BINARY_OP(OP) \
CELL OP(CELL x, CELL y) \
case COMPLEX_TYPE: \
return OP##_complex((COMPLEX*)UNTAG(x)); \
case BIGNUM_TYPE: \
- return OP##_bignum((BIGNUM*)UNTAG(x)); \
+ return OP##_bignum((ARRAY*)UNTAG(x)); \
case FLOAT_TYPE: \
return OP##_float((FLOAT*)UNTAG(x)); \
default: \
bool zerop(CELL tagged);
-FIXNUM to_fixnum(CELL tagged);
void primitive_to_fixnum(void);
-BIGNUM* to_bignum(CELL tagged);
void primitive_to_bignum(void);
void primitive_to_integer(void);
CELL number_eq(CELL x, CELL y);
#include "factor.h"
+void init_bignum(void)
+{
+ bignum_zero = bignum_allocate(0,0);
+
+ bignum_pos_one = bignum_allocate(1,0);
+ (BIGNUM_REF (bignum_pos_one, 0)) = 1;
+
+ bignum_neg_one = bignum_allocate(1,0);
+ (BIGNUM_REF (bignum_neg_one, 0)) = 1;
+}
+
void primitive_bignump(void)
{
drepl(tag_boolean(typep(BIGNUM_TYPE,dpeek())));
}
-BIGNUM* to_bignum(CELL tagged)
+ARRAY* to_bignum(CELL tagged)
{
RATIO* r;
FLOAT* f;
case FIXNUM_TYPE:
return fixnum_to_bignum(tagged);
case BIGNUM_TYPE:
- return (BIGNUM*)UNTAG(tagged);
+ return (ARRAY*)UNTAG(tagged);
case RATIO_TYPE:
r = (RATIO*)UNTAG(tagged);
return to_bignum(divint(r->numerator,r->denominator));
case FLOAT_TYPE:
f = (FLOAT*)UNTAG(tagged);
- return bignum((BIGNUM_2)f->n);
+ return s48_double_to_bignum(f->n);
default:
type_error(BIGNUM_TYPE,tagged);
return NULL; /* can't happen */
drepl(tag_object(to_bignum(dpeek())));
}
-CELL number_eq_bignum(BIGNUM* x, BIGNUM* y)
+CELL number_eq_bignum(ARRAY* x, ARRAY* y)
{
- return tag_boolean(x->n == y->n);
+ return tag_boolean(s48_bignum_equal_p(x,y));
}
-CELL add_bignum(BIGNUM* x, BIGNUM* y)
+CELL add_bignum(ARRAY* x, ARRAY* y)
{
- return tag_object(bignum(x->n + y->n));
+ return tag_object(s48_bignum_add(x,y));
}
-CELL subtract_bignum(BIGNUM* x, BIGNUM* y)
+CELL subtract_bignum(ARRAY* x, ARRAY* y)
{
- return tag_object(bignum(x->n - y->n));
+ return tag_object(s48_bignum_subtract(x,y));
}
-CELL multiply_bignum(BIGNUM* x, BIGNUM* y)
+CELL multiply_bignum(ARRAY* x, ARRAY* y)
{
- return tag_object(bignum(x->n * y->n));
+ return tag_object(s48_bignum_multiply(x,y));
}
BIGNUM_2 gcd_bignum(BIGNUM_2 x, BIGNUM_2 y)
}
}
-CELL divide_bignum(BIGNUM* x, BIGNUM* y)
+CELL divide_bignum(ARRAY* x, ARRAY* y)
{
- BIGNUM_2 _x = x->n;
+ /* BIGNUM_2 _x = x->n;
BIGNUM_2 _y = y->n;
BIGNUM_2 gcd;
if(_y == 0)
{
- /* FIXME */
+ /* FIXME
abort();
}
else if(_y < 0)
return tag_ratio(ratio(
tag_object(bignum(_x)),
tag_object(bignum(_y))));
- }
+ } */
+ return F;
}
-CELL divint_bignum(BIGNUM* x, BIGNUM* y)
+CELL divint_bignum(ARRAY* x, ARRAY* y)
{
- return tag_object(bignum(x->n / y->n));
+ ARRAY* q = s48_bignum_quotient(x,y);
+ if(q == NULL)
+ raise(SIGFPE);
+ return tag_object(q);
}
-CELL divfloat_bignum(BIGNUM* x, BIGNUM* y)
+CELL divfloat_bignum(ARRAY* x, ARRAY* y)
{
- BIGNUM_2 _x = x->n;
- BIGNUM_2 _y = y->n;
- return tag_object(make_float((double)_x / (double)_y));
+ return tag_object(make_float(
+ s48_bignum_to_double(x) /
+ s48_bignum_to_double(y)));
}
-CELL divmod_bignum(BIGNUM* x, BIGNUM* y)
+CELL divmod_bignum(ARRAY* x, ARRAY* y)
{
- dpush(tag_object(bignum(x->n / y->n)));
- return tag_object(bignum(x->n % y->n));
+ ARRAY* q;
+ ARRAY* r;
+ if(s48_bignum_divide(x,y,&q,&r))
+ raise(SIGFPE);
+ dpush(tag_object(q));
+ return tag_object(r);
}
-CELL mod_bignum(BIGNUM* x, BIGNUM* y)
+CELL mod_bignum(ARRAY* x, ARRAY* y)
{
- return tag_object(bignum(x->n % y->n));
+ ARRAY* r = s48_bignum_remainder(x,y);
+ if(r == NULL)
+ raise(SIGFPE);
+ return tag_object(r);
}
-CELL and_bignum(BIGNUM* x, BIGNUM* y)
+CELL and_bignum(ARRAY* x, ARRAY* y)
{
- return tag_object(bignum(x->n & y->n));
+ return tag_object(s48_bignum_bitwise_and(x,y));
}
-CELL or_bignum(BIGNUM* x, BIGNUM* y)
+CELL or_bignum(ARRAY* x, ARRAY* y)
{
- return tag_object(bignum(x->n | y->n));
+ return tag_object(s48_bignum_bitwise_ior(x,y));
}
-CELL xor_bignum(BIGNUM* x, BIGNUM* y)
+CELL xor_bignum(ARRAY* x, ARRAY* y)
{
- return tag_object(bignum(x->n ^ y->n));
+ return tag_object(s48_bignum_bitwise_xor(x,y));
}
-CELL shiftleft_bignum(BIGNUM* x, BIGNUM* y)
+CELL shiftleft_bignum(ARRAY* x, ARRAY* y)
{
- return tag_object(bignum(x->n << y->n));
+ return tag_object(s48_bignum_arithmetic_shift(x,
+ s48_bignum_to_long(y)));
}
-CELL shiftright_bignum(BIGNUM* x, BIGNUM* y)
+CELL shiftright_bignum(ARRAY* x, ARRAY* y)
{
- return tag_object(bignum(x->n >> y->n));
+ return tag_object(s48_bignum_arithmetic_shift(x,
+ -s48_bignum_to_long(y)));
}
-CELL less_bignum(BIGNUM* x, BIGNUM* y)
+CELL less_bignum(ARRAY* x, ARRAY* y)
{
- return tag_boolean(x->n < y->n);
+ return tag_boolean(
+ s48_bignum_compare(x,y)
+ == bignum_comparison_less);
}
-CELL lesseq_bignum(BIGNUM* x, BIGNUM* y)
+CELL lesseq_bignum(ARRAY* x, ARRAY* y)
{
- return tag_boolean(x->n <= y->n);
+ switch(s48_bignum_compare(x,y))
+ {
+ case bignum_comparison_less:
+ case bignum_comparison_equal:
+ return T;
+ case bignum_comparison_greater:
+ return F;
+ }
}
-CELL greater_bignum(BIGNUM* x, BIGNUM* y)
+CELL greater_bignum(ARRAY* x, ARRAY* y)
{
- return tag_boolean(x->n > y->n);
+ return tag_boolean(
+ s48_bignum_compare(x,y)
+ == bignum_comparison_greater);
+}
+
+CELL greatereq_bignum(ARRAY* x, ARRAY* y)
+{
+ switch(s48_bignum_compare(x,y))
+ {
+ case bignum_comparison_less:
+ return F;
+ case bignum_comparison_equal:
+ case bignum_comparison_greater:
+ return T;
+ }
}
-CELL greatereq_bignum(BIGNUM* x, BIGNUM* y)
+CELL not_bignum(ARRAY* x)
{
- return tag_boolean(x->n >= y->n);
+ return tag_object(s48_bignum_bitwise_not(x));
}
-CELL not_bignum(BIGNUM* x)
+void copy_bignum_constants(void)
{
- return tag_object(bignum(~(x->n)));
+ bignum_zero = copy_array(bignum_zero);
+ bignum_pos_one = copy_array(bignum_pos_one);
+ bignum_neg_one = copy_array(bignum_neg_one);
}
typedef long long BIGNUM_2;
-typedef struct {
- CELL header;
- CELL capacity;
- CELL sign;
- CELL fill; /* bad */
- BIGNUM_2 n;
-} BIGNUM;
-
-/* untagged */
-INLINE BIGNUM* allot_bignum()
-{
- /* Bignums are really retrofitted arrays */
- return (BIGNUM*)allot_array(BIGNUM_TYPE,4);
-}
-
-/* untagged */
-INLINE BIGNUM* bignum(BIGNUM_2 n)
-{
- BIGNUM* bignum = allot_bignum();
- bignum->n = n;
- return bignum;
-}
-
-INLINE BIGNUM* untag_bignum(CELL tagged)
+INLINE ARRAY* untag_bignum(CELL tagged)
{
type_check(BIGNUM_TYPE,tagged);
- return (BIGNUM*)UNTAG(tagged);
+ return (ARRAY*)UNTAG(tagged);
}
+ARRAY* bignum_zero;
+ARRAY* bignum_pos_one;
+ARRAY* bignum_neg_one;
+
+void init_bignum(void);
void primitive_bignump(void);
-BIGNUM* to_bignum(CELL tagged);
+ARRAY* to_bignum(CELL tagged);
void primitive_to_bignum(void);
-CELL number_eq_bignum(BIGNUM* x, BIGNUM* y);
-CELL add_bignum(BIGNUM* x, BIGNUM* y);
-CELL subtract_bignum(BIGNUM* x, BIGNUM* y);
-CELL multiply_bignum(BIGNUM* x, BIGNUM* y);
+CELL number_eq_bignum(ARRAY* x, ARRAY* y);
+CELL add_bignum(ARRAY* x, ARRAY* y);
+CELL subtract_bignum(ARRAY* x, ARRAY* y);
+CELL multiply_bignum(ARRAY* x, ARRAY* y);
BIGNUM_2 gcd_bignum(BIGNUM_2 x, BIGNUM_2 y);
-CELL divide_bignum(BIGNUM* x, BIGNUM* y);
-CELL divint_bignum(BIGNUM* x, BIGNUM* y);
-CELL divfloat_bignum(BIGNUM* x, BIGNUM* y);
-CELL divmod_bignum(BIGNUM* x, BIGNUM* y);
-CELL mod_bignum(BIGNUM* x, BIGNUM* y);
-CELL and_bignum(BIGNUM* x, BIGNUM* y);
-CELL or_bignum(BIGNUM* x, BIGNUM* y);
-CELL xor_bignum(BIGNUM* x, BIGNUM* y);
-CELL shiftleft_bignum(BIGNUM* x, BIGNUM* y);
-CELL shiftright_bignum(BIGNUM* x, BIGNUM* y);
-CELL less_bignum(BIGNUM* x, BIGNUM* y);
-CELL lesseq_bignum(BIGNUM* x, BIGNUM* y);
-CELL greater_bignum(BIGNUM* x, BIGNUM* y);
-CELL greatereq_bignum(BIGNUM* x, BIGNUM* y);
-CELL not_bignum(BIGNUM* x);
+CELL divide_bignum(ARRAY* x, ARRAY* y);
+CELL divint_bignum(ARRAY* x, ARRAY* y);
+CELL divfloat_bignum(ARRAY* x, ARRAY* y);
+CELL divmod_bignum(ARRAY* x, ARRAY* y);
+CELL mod_bignum(ARRAY* x, ARRAY* y);
+CELL and_bignum(ARRAY* x, ARRAY* y);
+CELL or_bignum(ARRAY* x, ARRAY* y);
+CELL xor_bignum(ARRAY* x, ARRAY* y);
+CELL shiftleft_bignum(ARRAY* x, ARRAY* y);
+CELL shiftright_bignum(ARRAY* x, ARRAY* y);
+CELL less_bignum(ARRAY* x, ARRAY* y);
+CELL lesseq_bignum(ARRAY* x, ARRAY* y);
+CELL greater_bignum(ARRAY* x, ARRAY* y);
+CELL greatereq_bignum(ARRAY* x, ARRAY* y);
+CELL not_bignum(ARRAY* x);
+void copy_bignum_constants(void);
load_image(argv[1]);
init_stacks();
init_io();
+ init_bignum();
init_signals();
args = F;
{
double f = untag_float(dpeek());
BIGNUM_2 f_raw = *(BIGNUM_2*)&f;
- drepl(tag_object(bignum(f_raw)));
+ drepl(tag_object(s48_long_to_bignum(f_raw)));
}
CELL number_eq_float(FLOAT* x, FLOAT* y)
copy_object(&T);
gc_debug("t",T);
copy_object(&callframe);
+ copy_bignum_constants();
for(ptr = ds_bot; ptr < ds; ptr += CELLS)
copy_object((void*)ptr);
{
struct timeval t;
gettimeofday(&t,NULL);
- dpush(tag_object(bignum(t.tv_sec * 1000 + t.tv_usec/1000)));
+ dpush(tag_object(s48_long_to_bignum(
+ t.tv_sec * 1000 + t.tv_usec/1000)));
}
void primitive_init_random(void)
void primitive_random_int(void)
{
- dpush(tag_object(bignum(random())));
+ dpush(tag_object(s48_long_to_bignum(random())));
}
void primitive_dump(void)
#include <stdlib.h> /* abort */
#include <math.h>
-/* Forward references */
-static int bignum_equal_p_unsigned(bignum_type, bignum_type);
-static enum bignum_comparison bignum_compare_unsigned(bignum_type, bignum_type);
-static bignum_type bignum_add_unsigned(bignum_type, bignum_type, int);
-static bignum_type bignum_subtract_unsigned(bignum_type, bignum_type);
-static bignum_type bignum_multiply_unsigned(bignum_type, bignum_type, int);
-static bignum_type bignum_multiply_unsigned_small_factor
- (bignum_type, bignum_digit_type, int);
-static void bignum_destructive_scale_up(bignum_type, bignum_digit_type);
-static void bignum_destructive_add(bignum_type, bignum_digit_type);
-static void bignum_divide_unsigned_large_denominator
- (bignum_type, bignum_type, bignum_type *, bignum_type *, int, int);
-static void bignum_destructive_normalization(bignum_type, bignum_type, int);
-static void bignum_destructive_unnormalization(bignum_type, int);
-static void bignum_divide_unsigned_normalized(bignum_type, bignum_type, bignum_type);
-static bignum_digit_type bignum_divide_subtract
- (bignum_digit_type *, bignum_digit_type *, bignum_digit_type,
- bignum_digit_type *);
-static void bignum_divide_unsigned_medium_denominator
- (bignum_type, bignum_digit_type, bignum_type *, bignum_type *, int, int);
-static bignum_digit_type bignum_digit_divide
- (bignum_digit_type, bignum_digit_type, bignum_digit_type, bignum_digit_type *);
-static bignum_digit_type bignum_digit_divide_subtract
- (bignum_digit_type, bignum_digit_type, bignum_digit_type, bignum_digit_type *);
-static void bignum_divide_unsigned_small_denominator
- (bignum_type, bignum_digit_type, bignum_type *, bignum_type *, int, int);
-static bignum_digit_type bignum_destructive_scale_down
- (bignum_type, bignum_digit_type);
-static bignum_type bignum_remainder_unsigned_small_denominator
- (bignum_type, bignum_digit_type, int);
-static bignum_type bignum_digit_to_bignum(bignum_digit_type, int);
-static bignum_type bignum_allocate(bignum_length_type, int);
-static bignum_type bignum_allocate_zeroed(bignum_length_type, int);
-static bignum_type bignum_shorten_length(bignum_type, bignum_length_type);
-static bignum_type bignum_trim(bignum_type);
-static bignum_type bignum_copy(bignum_type);
-static bignum_type bignum_new_sign(bignum_type, int);
-static bignum_type bignum_maybe_new_sign(bignum_type, int);
-static void bignum_destructive_copy(bignum_type, bignum_type);
-/* Unused
-static void bignum_destructive_zero(bignum_type);
-*/
-
-/* Added for bitwise operations. */
-static bignum_type bignum_magnitude_ash(bignum_type arg1, long n);
-static bignum_type bignum_pospos_bitwise_op(int op, bignum_type, bignum_type);
-static bignum_type bignum_posneg_bitwise_op(int op, bignum_type, bignum_type);
-static bignum_type bignum_negneg_bitwise_op(int op, bignum_type, bignum_type);
-static void bignum_negate_magnitude(bignum_type);
-static long bignum_unsigned_logcount(bignum_type arg);
-static int bignum_unsigned_logbitp(int shift, bignum_type bignum);
-
-static ARRAY* s48_bignum_zero;
-static ARRAY* s48_bignum_pos_one;
-static ARRAY* s48_bignum_neg_one;
-
/* Exports */
-/*
- * We have to allocate the cached constants slightly differently because
- * they have to be registered with the GC, which requires that we have
- * tagged pointers to them.
- */
-
-void
-s48_bignum_make_cached_constants(void)
-{
- bignum_type temp;
-
- s48_bignum_zero = bignum_allocate(0,0);
-
- s48_bignum_pos_one = bignum_allocate(1,0);
- (BIGNUM_REF (s48_bignum_pos_one, 0)) = 1;
-
- s48_bignum_neg_one = bignum_allocate(1,0);
- (BIGNUM_REF (s48_bignum_neg_one, 0)) = 1;
-}
-
int
s48_bignum_equal_p(bignum_type x, bignum_type y)
{
return (bignum_multiply_unsigned (x, y, negative_p));
}
-static int
+int
bignum_divide(bignum_type numerator, bignum_type denominator,
bignum_type * quotient, bignum_type * remainder)
{
/* Comparisons */
-static int
+int
bignum_equal_p_unsigned(bignum_type x, bignum_type y)
{
bignum_length_type length = (BIGNUM_LENGTH (x));
}
}
-static enum bignum_comparison
+enum bignum_comparison
bignum_compare_unsigned(bignum_type x, bignum_type y)
{
bignum_length_type x_length = (BIGNUM_LENGTH (x));
/* Addition */
-static bignum_type
+bignum_type
bignum_add_unsigned(bignum_type x, bignum_type y, int negative_p)
{
if ((BIGNUM_LENGTH (y)) > (BIGNUM_LENGTH (x)))
/* Subtraction */
-static bignum_type
+bignum_type
bignum_subtract_unsigned(bignum_type x, bignum_type y)
{
int negative_p;
Maximum value for carry: ((R * (R - 1)) + (R - 1))
where R == BIGNUM_RADIX_ROOT */
-static bignum_type
+bignum_type
bignum_multiply_unsigned(bignum_type x, bignum_type y, int negative_p)
{
if ((BIGNUM_LENGTH (y)) > (BIGNUM_LENGTH (x)))
}
}
-static bignum_type
+bignum_type
bignum_multiply_unsigned_small_factor(bignum_type x, bignum_digit_type y,
int negative_p)
{
return (bignum_trim (p));
}
-static void
+void
bignum_destructive_scale_up(bignum_type bignum, bignum_digit_type factor)
{
bignum_digit_type carry = 0;
#undef product_high
}
-static void
+void
bignum_destructive_add(bignum_type bignum, bignum_digit_type n)
{
bignum_digit_type * scan = (BIGNUM_START_PTR (bignum));
volume 2, "Seminumerical Algorithms"
section 4.3.1, "Multiple-Precision Arithmetic". */
-static void
+void
bignum_divide_unsigned_large_denominator(bignum_type numerator,
bignum_type denominator,
bignum_type * quotient,
return;
}
-static void
+void
bignum_divide_unsigned_normalized(bignum_type u, bignum_type v, bignum_type q)
{
bignum_length_type u_length = (BIGNUM_LENGTH (u));
#undef qj
}
-static bignum_digit_type
+bignum_digit_type
bignum_divide_subtract(bignum_digit_type * v_start,
bignum_digit_type * v_end,
bignum_digit_type guess,
return (guess - 1);
}
-static void
+void
bignum_divide_unsigned_medium_denominator(bignum_type numerator,
bignum_digit_type denominator,
bignum_type * quotient,
return;
}
-static void
+void
bignum_destructive_normalization(bignum_type source, bignum_type target,
int shift_left)
{
return;
}
-static void
+void
bignum_destructive_unnormalization(bignum_type bignum, int shift_right)
{
bignum_digit_type * start = (BIGNUM_START_PTR (bignum));
qn = (bignum_digit_divide_subtract (v1, v2, guess, (&u[j]))); \
}
-static bignum_digit_type
+bignum_digit_type
bignum_digit_divide(bignum_digit_type uh, bignum_digit_type ul,
bignum_digit_type v,
bignum_digit_type * q) /* return value */
} \
}
-static bignum_digit_type
+bignum_digit_type
bignum_digit_divide_subtract(bignum_digit_type v1, bignum_digit_type v2,
bignum_digit_type guess, bignum_digit_type * u)
{
#undef BDDS_MULSUB
#undef BDDS_ADD
-static void
+void
bignum_divide_unsigned_small_denominator(bignum_type numerator,
bignum_digit_type denominator,
bignum_type * quotient,
(quotient_high < BIGNUM_RADIX_ROOT), after which it is easy to see
that all digits are < BIGNUM_RADIX. */
-static bignum_digit_type
+bignum_digit_type
bignum_destructive_scale_down(bignum_type bignum, bignum_digit_type denominator)
{
bignum_digit_type numerator;
#undef quotient_high
}
-static bignum_type
+bignum_type
bignum_remainder_unsigned_small_denominator(
bignum_type n, bignum_digit_type d, int negative_p)
{
return (bignum_digit_to_bignum (r, negative_p));
}
-static bignum_type
+bignum_type
bignum_digit_to_bignum(bignum_digit_type digit, int negative_p)
{
if (digit == 0)
/* Allocation */
-static bignum_type
+bignum_type
bignum_allocate(bignum_length_type length, int negative_p)
{
BIGNUM_ASSERT ((length >= 0) || (length < BIGNUM_RADIX));
}
}
-static bignum_type
+bignum_type
bignum_allocate_zeroed(bignum_length_type length, int negative_p)
{
BIGNUM_ASSERT ((length >= 0) || (length < BIGNUM_RADIX));
}
}
-static bignum_type
+bignum_type
bignum_shorten_length(bignum_type bignum, bignum_length_type length)
{
bignum_length_type current_length = (BIGNUM_LENGTH (bignum));
return (bignum);
}
-static bignum_type
+bignum_type
bignum_trim(bignum_type bignum)
{
bignum_digit_type * start = (BIGNUM_START_PTR (bignum));
/* Copying */
-static bignum_type
+bignum_type
bignum_copy(bignum_type source)
{
bignum_type target =
return (target);
}
-static bignum_type
+bignum_type
bignum_new_sign(bignum_type bignum, int negative_p)
{
bignum_type result =
return (result);
}
-static bignum_type
+bignum_type
bignum_maybe_new_sign(bignum_type bignum, int negative_p)
{
#ifndef BIGNUM_FORCE_NEW_RESULTS
}
}
-static void
+void
bignum_destructive_copy(bignum_type source, bignum_type target)
{
bignum_digit_type * scan_source = (BIGNUM_START_PTR (source));
}
/* Unused
-static void
+void
bignum_destructive_zero(bignum_type bignum)
{
bignum_digit_type * scan = (BIGNUM_START_PTR (bignum));
/* ash for the magnitude */
/* assume arg1 is a big number, n is a long */
-static bignum_type
+bignum_type
bignum_magnitude_ash(bignum_type arg1, long n)
{
bignum_type result;
return (bignum_trim (result));
}
-static bignum_type
+bignum_type
bignum_pospos_bitwise_op(int op, bignum_type arg1, bignum_type arg2)
{
bignum_type result;
return bignum_trim(result);
}
-static bignum_type
+bignum_type
bignum_posneg_bitwise_op(int op, bignum_type arg1, bignum_type arg2)
{
bignum_type result;
return bignum_trim(result);
}
-static bignum_type
+bignum_type
bignum_negneg_bitwise_op(int op, bignum_type arg1, bignum_type arg2)
{
bignum_type result;
return bignum_trim(result);
}
-static void
+void
bignum_negate_magnitude(bignum_type arg)
{
bignum_digit_type *scan;
}
}
-static long
+long
bignum_unsigned_logcount(bignum_type arg)
{
: bignum_unsigned_logbitp (shift,arg));
}
-static int
+int
bignum_unsigned_logbitp(int shift, bignum_type bignum)
{
bignum_length_type len = (BIGNUM_LENGTH (bignum));
};
typedef void * bignum_procedure_context;
-extern int s48_bignum_equal_p(bignum_type, bignum_type);
-extern enum bignum_comparison s48_bignum_test(bignum_type);
-extern enum bignum_comparison s48_bignum_compare(bignum_type, bignum_type);
-extern bignum_type s48_bignum_add(bignum_type, bignum_type);
-extern bignum_type s48_bignum_subtract(bignum_type, bignum_type);
-extern bignum_type s48_bignum_negate(bignum_type);
-extern bignum_type s48_bignum_multiply(bignum_type, bignum_type);
-extern int s48_bignum_divide(bignum_type numerator, bignum_type denominator,
+int s48_bignum_equal_p(bignum_type, bignum_type);
+enum bignum_comparison s48_bignum_test(bignum_type);
+enum bignum_comparison s48_bignum_compare(bignum_type, bignum_type);
+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);
-extern bignum_type s48_bignum_quotient(bignum_type, bignum_type);
-extern bignum_type s48_bignum_remainder(bignum_type, bignum_type);
-extern bignum_type s48_long_to_bignum(long);
-extern bignum_type s48_ulong_to_bignum(unsigned long);
-extern long s48_bignum_to_long(bignum_type);
-extern unsigned long s48_bignum_to_ulong(bignum_type);
-extern bignum_type s48_double_to_bignum(double);
-extern double s48_bignum_to_double(bignum_type);
-extern int s48_bignum_fits_in_word_p(bignum_type, long word_length,
+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);
+bignum_type s48_ulong_to_bignum(unsigned long);
+long s48_bignum_to_long(bignum_type);
+unsigned long s48_bignum_to_ulong(bignum_type);
+bignum_type s48_double_to_bignum(double);
+double s48_bignum_to_double(bignum_type);
+int s48_bignum_fits_in_word_p(bignum_type, long word_length,
int twos_complement_p);
-extern bignum_type s48_bignum_length_in_bits(bignum_type);
-extern bignum_type s48_bignum_length_upper_limit(void);
-extern bignum_type s48_digit_stream_to_bignum
+bignum_type s48_bignum_length_in_bits(bignum_type);
+bignum_type s48_bignum_length_upper_limit(void);
+bignum_type s48_digit_stream_to_bignum
(unsigned int n_digits,
unsigned int (*producer(bignum_procedure_context)),
bignum_procedure_context context,
unsigned int radix,
int negative_p);
-extern long s48_bignum_max_digit_stream_radix(void);
+long s48_bignum_max_digit_stream_radix(void);
/* Added bitwise operators. */
-extern bignum_type s48_bignum_bitwise_not(bignum_type),
+bignum_type s48_bignum_bitwise_not(bignum_type),
s48_bignum_arithmetic_shift(bignum_type, long),
s48_bignum_bitwise_and(bignum_type, bignum_type),
s48_bignum_bitwise_ior(bignum_type, bignum_type),
s48_bignum_bitwise_xor(bignum_type, bignum_type);
-extern int s48_bignum_oddp(bignum_type);
-extern long s48_bignum_bit_count(bignum_type);
+int s48_bignum_oddp(bignum_type);
+long s48_bignum_bit_count(bignum_type);
+
+/* Forward references */
+int bignum_equal_p_unsigned(bignum_type, bignum_type);
+enum bignum_comparison bignum_compare_unsigned(bignum_type, bignum_type);
+bignum_type bignum_add_unsigned(bignum_type, bignum_type, int);
+bignum_type bignum_subtract_unsigned(bignum_type, bignum_type);
+bignum_type bignum_multiply_unsigned(bignum_type, bignum_type, int);
+bignum_type bignum_multiply_unsigned_small_factor
+ (bignum_type, bignum_digit_type, int);
+void bignum_destructive_scale_up(bignum_type, bignum_digit_type);
+void bignum_destructive_add(bignum_type, bignum_digit_type);
+void bignum_divide_unsigned_large_denominator
+ (bignum_type, bignum_type, bignum_type *, bignum_type *, int, int);
+void bignum_destructive_normalization(bignum_type, bignum_type, int);
+void bignum_destructive_unnormalization(bignum_type, int);
+void bignum_divide_unsigned_normalized(bignum_type, bignum_type, bignum_type);
+bignum_digit_type bignum_divide_subtract
+ (bignum_digit_type *, bignum_digit_type *, bignum_digit_type,
+ bignum_digit_type *);
+void bignum_divide_unsigned_medium_denominator
+ (bignum_type, bignum_digit_type, bignum_type *, bignum_type *, int, int);
+bignum_digit_type bignum_digit_divide
+ (bignum_digit_type, bignum_digit_type, bignum_digit_type, bignum_digit_type *);
+bignum_digit_type bignum_digit_divide_subtract
+ (bignum_digit_type, bignum_digit_type, bignum_digit_type, bignum_digit_type *);
+void bignum_divide_unsigned_small_denominator
+ (bignum_type, bignum_digit_type, bignum_type *, bignum_type *, int, int);
+bignum_digit_type bignum_destructive_scale_down
+ (bignum_type, bignum_digit_type);
+bignum_type bignum_remainder_unsigned_small_denominator
+ (bignum_type, bignum_digit_type, int);
+bignum_type bignum_digit_to_bignum(bignum_digit_type, int);
+bignum_type bignum_allocate(bignum_length_type, int);
+bignum_type bignum_allocate_zeroed(bignum_length_type, int);
+bignum_type bignum_shorten_length(bignum_type, bignum_length_type);
+bignum_type bignum_trim(bignum_type);
+bignum_type bignum_copy(bignum_type);
+bignum_type bignum_new_sign(bignum_type, int);
+bignum_type bignum_maybe_new_sign(bignum_type, int);
+void bignum_destructive_copy(bignum_type, bignum_type);
+/* Unused
+void bignum_destructive_zero(bignum_type);
+*/
+
+/* Added for bitwise operations. */
+bignum_type bignum_magnitude_ash(bignum_type arg1, long n);
+bignum_type bignum_pospos_bitwise_op(int op, bignum_type, bignum_type);
+bignum_type bignum_posneg_bitwise_op(int op, bignum_type, bignum_type);
+bignum_type bignum_negneg_bitwise_op(int op, bignum_type, bignum_type);
+void bignum_negate_magnitude(bignum_type);
+long bignum_unsigned_logcount(bignum_type arg);
+int bignum_unsigned_logbitp(int shift, bignum_type bignum);
/* BIGNUM_REDUCE_LENGTH allows the memory system to reclaim some
space when a bignum's length is reduced from its original value. */
#define BIGNUM_REDUCE_LENGTH(target, source, length) \
- target = shrink_array(source, length)
+ target = shrink_array(source, length + 1)
extern ARRAY* shrink_array(ARRAY* array, CELL capacity);
/* BIGNUM_DEALLOCATE is called when disposing of bignums which are
#define BIGNUM_START_PTR(bignum) \
((BIGNUM_TO_POINTER (bignum)) + 1)
-#define BIGNUM_LENGTH(bignum) (bignum->capacity - 1)
+#define BIGNUM_LENGTH(bignum) ((bignum)->capacity - 1)
-#define BIGNUM_NEGATIVE_P(bignum) (AREF(bignum,0) != 0)
+#define BIGNUM_NEGATIVE_P(bignum) (get(AREF(bignum,0)) != 0)
#define BIGNUM_SET_NEGATIVE_P(bignum,neg) put(AREF(bignum,0),neg)
#define BIGNUM_ZERO_P(bignum) \
/* These definitions are here to facilitate caching of the constants
0, 1, and -1. */
-#define BIGNUM_ZERO() s48_bignum_zero
+#define BIGNUM_ZERO() bignum_zero
#define BIGNUM_ONE(neg_p) \
- (neg_p ? s48_bignum_pos_one : s48_bignum_neg_one)
+ (neg_p ? bignum_pos_one : bignum_neg_one)
#define HD_LOW(digit) ((digit) & BIGNUM_HALF_DIGIT_MASK)
#define HD_HIGH(digit) ((digit) >> BIGNUM_HALF_DIGIT_LENGTH)
void primitive_string_hashcode(void)
{
- drepl(tag_object(bignum(untag_string(dpeek())->hashcode)));
+ drepl(tag_object(s48_long_to_bignum(
+ untag_string(dpeek())->hashcode)));
}
CELL index_of_ch(CELL index, STRING* string, CELL ch)