mirror of
https://github.com/justinethier/cyclone.git
synced 2025-07-09 14:07:34 +02:00
Stage bignum2 addition
This commit is contained in:
parent
9472304576
commit
a0ff18937c
2 changed files with 56 additions and 0 deletions
|
@ -852,6 +852,8 @@ typedef struct {
|
||||||
} bignum2_type;
|
} bignum2_type;
|
||||||
|
|
||||||
#define C_bignum_digits(n) (&(((bignum2_type *)n)->sign) + 1)
|
#define C_bignum_digits(n) (&(((bignum2_type *)n)->sign) + 1)
|
||||||
|
#define C_bignum_size(n) (((bignum2_type *)n)->num_digits)
|
||||||
|
#define C_bignum_sign(n) (((bignum2_type *)n)->sign)
|
||||||
|
|
||||||
// TODO: covert applicable definitions below -
|
// TODO: covert applicable definitions below -
|
||||||
// #ifdef C_SIXTY_FOUR
|
// #ifdef C_SIXTY_FOUR
|
||||||
|
|
54
runtime.c
54
runtime.c
|
@ -2599,6 +2599,60 @@ string_type *bignum2string(void *data, bignum2_type *bn, int radix)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: static
|
||||||
|
//object bignum_plus_unsigned(C_word **ptr, C_word x, C_word y, C_word negp)
|
||||||
|
object bignum2_plus_unsigned(void *data, bignum2_type *x, bignum2_type *y, int negp)
|
||||||
|
{
|
||||||
|
object result;
|
||||||
|
uint32_t size, sum, digit, *scan_y, *end_y, *scan_r, *end_r;
|
||||||
|
int carry = 0;
|
||||||
|
|
||||||
|
if (y->num_digits > x->num_digits) { /* Ensure size(y) <= size(x) */
|
||||||
|
object z = x;
|
||||||
|
x = y;
|
||||||
|
y = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = x->num_digits + 1; /* One more digit, for possible carry. */
|
||||||
|
result = gc_alloc_bignum2(data, size);
|
||||||
|
C_bignum_sign(result) = negp;
|
||||||
|
|
||||||
|
scan_y = C_bignum_digits(y);
|
||||||
|
end_y = scan_y + C_bignum_size(y);
|
||||||
|
scan_r = C_bignum_digits(result);
|
||||||
|
end_r = scan_r + C_bignum_size(result);
|
||||||
|
|
||||||
|
/* Copy x into r so we can operate on two pointers, which is faster
|
||||||
|
* than three, and we can stop earlier after adding y. It's slower
|
||||||
|
* if x and y have equal length. On average it's slightly faster.
|
||||||
|
*/
|
||||||
|
bignum_digits_destructive_copy(result, x);
|
||||||
|
*(end_r-1) = 0; /* Ensure most significant digit is initialised */
|
||||||
|
|
||||||
|
/* Move over x and y simultaneously, destructively adding digits w/ carry. */
|
||||||
|
while (scan_y < end_y) {
|
||||||
|
digit = *scan_r;
|
||||||
|
if (carry) {
|
||||||
|
sum = digit + *scan_y++ + 1;
|
||||||
|
carry = sum <= digit;
|
||||||
|
} else {
|
||||||
|
sum = digit + *scan_y++;
|
||||||
|
carry = sum < digit;
|
||||||
|
}
|
||||||
|
(*scan_r++) = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The end of y, the smaller number. Propagate carry into the rest of x. */
|
||||||
|
while (carry) {
|
||||||
|
sum = (*scan_r) + 1;
|
||||||
|
carry = (sum == 0);
|
||||||
|
(*scan_r++) = sum;
|
||||||
|
}
|
||||||
|
assert(scan_r <= end_r);
|
||||||
|
|
||||||
|
return C_bignum_simplify(result);
|
||||||
|
}
|
||||||
|
|
||||||
object Cyc_symbol2string(void *data, object cont, object sym)
|
object Cyc_symbol2string(void *data, object cont, object sym)
|
||||||
{
|
{
|
||||||
Cyc_check_sym(data, sym);
|
Cyc_check_sym(data, sym);
|
||||||
|
|
Loading…
Add table
Reference in a new issue