mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
fixup! Merge branch 'bigint-embed' of https://github.com/dearblue/mruby into bigint-embed
This commit is contained in:
@@ -399,6 +399,7 @@ mpz_sub(mrb_state *mrb, struct RBigint *z, struct RBigint *x, struct RBigint *y)
|
||||
mpz_set(mrb, &u, y);
|
||||
RBIGINT_SET_SIGN(&u, -(RBIGINT_SIGN(&u)));
|
||||
mpz_add(mrb, z, x, &u);
|
||||
mpz_clear(mrb, &u);
|
||||
}
|
||||
|
||||
/* x = y - n */
|
||||
@@ -418,7 +419,7 @@ static void
|
||||
mpz_mul(mrb_state *mrb, struct RBigint *ww, struct RBigint *u, struct RBigint *v)
|
||||
{
|
||||
if (zero_p(u) || zero_p(v)) {
|
||||
zero(ww);
|
||||
mpz_set_int(mrb, ww, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -496,7 +497,7 @@ urshift(mrb_state *mrb, struct RBigint *c1, struct RBigint *a, size_t n)
|
||||
if (n == 0)
|
||||
mpz_set(mrb, c1, a);
|
||||
else if (uzero_p(a)) {
|
||||
zero(c1);
|
||||
mpz_set_int(mrb, c1, 0);
|
||||
}
|
||||
else {
|
||||
struct RBigint c;
|
||||
@@ -527,7 +528,7 @@ ulshift(mrb_state *mrb, struct RBigint *c1, struct RBigint *a, size_t n)
|
||||
if (n == 0)
|
||||
mpz_set(mrb, c1, a);
|
||||
else if (uzero_p(a)) {
|
||||
zero(c1);
|
||||
mpz_set_int(mrb, c1, 0);
|
||||
}
|
||||
else {
|
||||
mp_limb cc = 0;
|
||||
@@ -760,78 +761,13 @@ mpz_sizeinbase(struct RBigint *x, mrb_int base)
|
||||
return bits/(j-1)+1;
|
||||
}
|
||||
|
||||
/* x = y * n (only called from mpz_init_set_str) */
|
||||
/* assumes x and n are positive or zero */
|
||||
/* assumes n is small (fits in mp_limb) */
|
||||
static void
|
||||
mpz_mul_int(mrb_state *mrb, mpz_t *x, mrb_int n)
|
||||
{
|
||||
if (n == 0 || zero_p(x)) {
|
||||
zero(x);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t x_sz = x->sz;
|
||||
size_t new_sz = x_sz + 1; // Maximum possible size after multiplication
|
||||
|
||||
// Reallocate x if necessary
|
||||
mpz_realloc(mrb, x, new_sz);
|
||||
|
||||
mp_dbl_limb cc = 0;
|
||||
mp_limb n_limb = (mp_limb)n;
|
||||
|
||||
for (size_t i = 0; i < x_sz; i++) {
|
||||
// Multiply each limb and add carry
|
||||
cc += (mp_dbl_limb)x->p[i] * n_limb;
|
||||
x->p[i] = LOW(cc);
|
||||
cc = HIGH(cc);
|
||||
}
|
||||
|
||||
if (cc) {
|
||||
// If there is a remaining carry, store it
|
||||
x->p[x_sz] = (mp_limb)cc;
|
||||
} else {
|
||||
x->sz = x_sz;
|
||||
}
|
||||
|
||||
x->sn = 1;
|
||||
trim(x);
|
||||
}
|
||||
|
||||
/* x = y + n (only called from mpz_init_set_str) */
|
||||
/* assumes x and n are positive or zero */
|
||||
/* assumes n is small (fits in mp_limb) */
|
||||
static void
|
||||
mpz_add_int(mrb_state *mrb, mpz_t *x, mrb_int n)
|
||||
{
|
||||
if (n == 0) {
|
||||
// If n is zero, no operation is needed
|
||||
return;
|
||||
}
|
||||
|
||||
// Assume x is positive and n is a small positive integer (n < 36)
|
||||
mp_dbl_limb carry = n; // Initialize carry with n
|
||||
for (size_t i = 0; i < x->sz && carry; i++) {
|
||||
carry += (mp_dbl_limb)x->p[i]; // Add current limb and carry
|
||||
x->p[i] = LOW(carry); // Store lower 32 bits in current limb
|
||||
carry = HIGH(carry); // Update carry with higher bits
|
||||
}
|
||||
|
||||
if (carry != 0) {
|
||||
mpz_realloc(mrb, x, x->sz + 1);
|
||||
x->p[x->sz-1] = (mp_limb)carry;
|
||||
x->sn = 1;
|
||||
}
|
||||
trim(x);
|
||||
}
|
||||
|
||||
static int
|
||||
mpz_init_set_str(mrb_state *mrb, struct RBigint *x, const char *s, mrb_int len, mrb_int base)
|
||||
{
|
||||
int retval = 0;
|
||||
short sn;
|
||||
uint8_t k;
|
||||
|
||||
mpz_init(mrb, x);
|
||||
zero(x);
|
||||
if (*s == '-') {
|
||||
sn = -1; s++;
|
||||
@@ -854,8 +790,8 @@ mpz_init_set_str(mrb_state *mrb, struct RBigint *x, const char *s, mrb_int len,
|
||||
retval = (-1);
|
||||
break;
|
||||
}
|
||||
mpz_mul_int(mrb, x, base);
|
||||
mpz_add_int(mrb, x, k);
|
||||
mpz_mul_int(mrb, x, x, base);
|
||||
mpz_add_int(mrb, x, x, k);
|
||||
}
|
||||
RBIGINT_SET_SIGN(x, sn);
|
||||
return retval;
|
||||
|
||||
Reference in New Issue
Block a user