diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c index ce91232f29..dc3022c899 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -13,6 +13,17 @@ #include #include "bigint.h" +#define DIG_SIZE (MPZ_DIG_SIZE) +#define DIG_BASE (1ULL << DIG_SIZE) +#define DIG_MASK (DIG_BASE - 1) +#define HIGH(x) ((x) >> DIG_SIZE) +#define LOW(x) ((x) & DIG_MASK) + +#define iabs(x) ((x>0) ? (x) : (-x)) +#define imax(x,y) ((x>y)?x:y) +#define imin(x,y) ((xsz)?(x)->p[i]:0) + static void mpz_init(mrb_state *mrb, mpz_t *s) { @@ -21,32 +32,43 @@ mpz_init(mrb_state *mrb, mpz_t *s) s->sz=0; } -static void -mpz_init_set(mrb_state *mrb, mpz_t *s, mpz_t *t) -{ - s->p = (mp_limb*)mrb_malloc(mrb, sizeof(mp_limb)*t->sz); - for (size_t i=0; i < t->sz; i++) - (s->p)[i] = (t->p)[i]; - - s->sn = t->sn; - s->sz = t->sz; -} - static void mpz_realloc(mrb_state *mrb, mpz_t *x, size_t size) { if (x->sz < size) { - x->p=(mp_limb*)mrb_realloc(mrb,x->p,size * sizeof(mp_limb)); + x->p=(mp_limb*)mrb_realloc(mrb,x->p,size*sizeof(mp_limb)); for (size_t i=x->sz; ip)[i] = 0; x->sz = size; } } +static void +mpz_set(mrb_state *mrb, mpz_t *y, mpz_t *x) +{ + size_t i, k = x->sz; + + mpz_realloc(mrb, y, (size_t)k); + for (i=0;i < k; i++) + (y->p)[i] = (x->p)[i]; + + for (;isz;i++) + (y->p)[i] = 0; + + y->sn = x->sn; +} + +static void +mpz_init_set(mrb_state *mrb, mpz_t *s, mpz_t *t) +{ + s->p = NULL; + mpz_set(mrb, s, t); +} + static void mpz_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) { - mp_limb u; + mrb_uint u; size_t len; if (v == 0) { @@ -62,11 +84,15 @@ mpz_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) if (v == MRB_INT_MIN) u = v; else u = -v; } - if ((u & LC) == 0) len = 1; - else len = 2; + if (sizeof(mrb_int) > sizeof(mp_limb) && HIGH(u) != 0) { + len = 2; + } + else { + len = 1; + } mpz_realloc(mrb, y, len); - y->p[0] = u & LMAX; - if (len > 1) y->p[1] = (u & LC) >> DIGITBITS; + y->p[0] = LOW(u); + if (len > 1) y->p[1] = HIGH(u); } static void @@ -79,8 +105,7 @@ mpz_init_set_int(mrb_state *mrb, mpz_t *y, mrb_int v) static void mpz_clear(mrb_state *mrb, mpz_t *s) { - if (s->p) - mrb_free(mrb, s->p); + if (s->p) mrb_free(mrb, s->p); s->p=NULL; s->sn=0; s->sz=0; @@ -97,54 +122,40 @@ digits(mpz_t *x) return i+1; } -/* y = x */ static void -mpz_set(mrb_state *mrb, mpz_t *y, mpz_t *x) +trim(mpz_t *x) { - size_t i,k = x->sz; - - mpz_realloc(mrb, y, (size_t)k); - for (i=0;i < k; i++) - (y->p)[i] = (x->p)[i]; - - for (;isz;i++) - (y->p)[i] = 0; - - y->sn = x->sn; + while (x->sz && x->p[x->sz-1] == 0) { + x->sz--; + } } /* z = x + y, without regard for sign */ static void uadd(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) { - mp_limb c; - size_t i; - mpz_t *t; - if (y->sz < x->sz) { + mpz_t *t; /* swap x,y */ t=x; x=y; y=t; } /* now y->sz >= x->sz */ - mpz_realloc(mrb, z, (size_t)((y->sz)+1)); - c=0; + mp_limb2 c = 0; + size_t i; for (i=0; isz; i++) { - if ((z->p[i] = y->p[i] + x->p[i] + c) & CMASK) { - c=1; - (z->p[i]) &=LMAX; - } - else - c=0; + c += (mp_limb2)y->p[i] + (mp_limb2)x->p[i]; + z->p[i] = LOW(c); + c >>= DIG_SIZE; } for (;isz; i++) { - if ((z->p[i] = (y->p[i] + c)) & CMASK) - z->p[i]=0; - else - c=0; + c += y->p[i]; + z->p[i] = LOW(c); + c >>= DIG_SIZE; } - (z->p)[y->sz]=c; + z->p[y->sz]=c; + trim(z); } /* z = y - x, ignoring sign */ @@ -152,31 +163,34 @@ uadd(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) static void usub(mrb_state *mrb, mpz_t *z, mpz_t *y, mpz_t *x) { - mp_limb b,m; mpz_realloc(mrb, z, (size_t)(y->sz)); - b=0; - for (size_t i=0;isz;i++) { - m=((y->p)[i]-b)-dg(x,i); - if (m < 0) { - b = 1; - m = LMAX + 1 + m; - } - else - b = 0; - z->p[i] = m; + mp_limb2s b = 0; + size_t i; + for (i=0;isz;i++) { + b += (mp_limb2s)y->p[i]; + b -= (mp_limb2s)x->p[i]; + z->p[i] = LOW(b); + b = HIGH(b); } + for (;isz; i++) { + b += y->p[i]; + z->p[i] = LOW(b); + b = HIGH(b); + } + z->sz = digits(z); } /* compare abs(x) and abs(y) */ static int ucmp(mpz_t *y, mpz_t *x) { - size_t i; - for (i=imax(x->sz,y->sz)-1;;i--) { - if (dg(y,i) < dg(x,i)) - return (-1); - else if (dg(y,i) > dg(x,i)) - return 1; + if (y->sz < x->sz) return -1; + if (y->sz > x->sz) return 1; + for (size_t i=x->sz-1;;i--) { + mp_limb a = y->p[i]; + mp_limb b = x->p[i]; + if (a > b) return 1; + if (a < b) return -1; if (i == 0) break; } return 0; @@ -195,8 +209,13 @@ static void zero(mpz_t *x) { x->sn=0; - for (size_t i=0;isz;i++) - (x->p)[i] = 0; + if (x->p) { + x->sz=1; + x->p[0]=0; + } + else { + x->sz=0; + } } /* z = x + y */ @@ -237,6 +256,7 @@ mpz_add(mrb_state *mrb, mpz_t *zz, mpz_t *x, mpz_t *y) z.sn = (x->sn < 0 && y->sn > 0) ? 1 : (-1); } } + trim(&z); mpz_set(mrb,zz,&z); mpz_clear(mrb,&z); } @@ -268,8 +288,6 @@ static void mpz_mul(mrb_state *mrb, mpz_t *ww, mpz_t *u, mpz_t *v) { size_t i,j; - mp_limb t0,t1,t2,t3; - mp_limb cc; mpz_t w; if (uzero(u) || uzero(v)) { @@ -278,41 +296,23 @@ mpz_mul(mrb_state *mrb, mpz_t *ww, mpz_t *u, mpz_t *v) } mpz_init(mrb, &w); mpz_realloc(mrb, &w, (size_t)(u->sz + v->sz)); - for (j=0; j < 2*u->sz; j++) { - cc = (mp_limb)0; - t3 = hd(u,j); - for (i=0; i < 2*v->sz; i++) { - t0 = t3 * hd(v,i); - t1 = HIGH(t0); t0 = LOW(t0); - if ((i+j)%2) - t2 = HIGH(w.p[(i+j)/2]); - else - t2 = LOW(w.p[(i+j)/2]); - t2 += cc; - if (t2 & HCMASK) { - cc = 1; t2&=HLMAX; - } - else - cc = 0; - t2 += t0; - if (t2 & HCMASK) { - cc++ ; t2&=HLMAX; - } - cc+=t1; - if ((i+j)%2) - w.p[(i+j)/2] = LOW(w.p[(i+j)/2]) | - (t2 << HALFDIGITBITS); - else - w.p[(i+j)/2] = (HIGH(w.p[(i+j)/2]) << HALFDIGITBITS) | t2; + for (j=0; j < u->sz; j++) { + mp_limb2 cc = (mp_limb)0; + mp_limb u0 = u->p[j]; + if (u0 == 0) continue; + for (i=0; i < v->sz; i++) { + mp_limb v0 = v->p[i]; + if (v0 == 0) continue; + cc += (mp_limb2)w.p[i+j] + (mp_limb2)u0 * (mp_limb2)v0; + w.p[i+j] = LOW(cc); + cc = HIGH(cc); } if (cc) { - if ((j+i)%2) - w.p[(i+j)/2] += cc << HALFDIGITBITS; - else - w.p[(i+j)/2] += cc; + w.p[i+j] = cc; } } w.sn = (u->sn) * (v->sn); + trim(&w); mpz_set(mrb, ww, &w); mpz_clear(mrb, &w); } @@ -320,7 +320,13 @@ mpz_mul(mrb_state *mrb, mpz_t *ww, mpz_t *u, mpz_t *v) static void mpz_mul_int(mrb_state *mrb, mpz_t *x, mpz_t *y, mrb_int n) { + if (n == 0) { + zero(x); + return; + } + mpz_t z; + mpz_init_set_int(mrb,&z,n); mpz_mul(mrb,x,y,&z); mpz_clear(mrb,&z); @@ -331,60 +337,63 @@ static int lzb(mp_limb x) { #if (defined(__GNUC__) || __has_builtin(__builtin_clz)) - /* subtract 2 because DIGITBITS = LONGBITS-2 */ - if (sizeof(mp_limb) == sizeof(long long)) - return __builtin_clzll(x)-2; - else if (sizeof(mp_limb) == sizeof(int)) - return __builtin_clz(x)-2; + if (sizeof(mp_limb) == sizeof(int64_t)) + return __builtin_clzll(x); + else if (sizeof(mp_limb) == sizeof(int32_t)) + return __builtin_clz(x); #endif mp_limb i; int j=0; - for (i = ((mp_limb)1 << (DIGITBITS-1)); i && !(x&i) ; j++,i>>=1) + for (i = ((mp_limb)1 << (DIG_SIZE-1)); i && !(x&i) ; j++,i>>=1) ; return j; } /* c1 = a>>n */ -/* n must be < DIGITBITS */ +/* n must be < DIG_SIZE */ static void urshift(mrb_state *mrb, mpz_t *c1, mpz_t *a, size_t n) { - mp_limb cc = 0; - mrb_assert(n < DIGITBITS); + mrb_assert(n < DIG_SIZE); if (n == 0) mpz_set(mrb, c1, a); else { - mpz_t c; int i; - mp_limb rm = (((mp_limb)1<sz)); - for (i=a->sz-1; i>=0; i--) { - c.p[i] = ((a->p[i] >> n) | cc) & LMAX; - cc = (a->p[i] & rm) << (DIGITBITS - n); + for (size_t i=a->sz-1; ; i--) { + c.p[i] = ((a->p[i] >> n) | cc) & DIG_MASK; + cc = (a->p[i] & rm) << (DIG_SIZE - n); + if (i == 0) break; } + trim(&c); mpz_set(mrb,c1,&c); mpz_clear(mrb,&c); } } /* c1 = a<sz + 1)); + size_t i; for (i=0; isz; i++) { - c.p[i] = (((mp_ulimb)a->p[i] << n) | cc) & LMAX; - cc = (a->p[i] & rm) >> (DIGITBITS-n); + c.p[i] = ((a->p[i] << n) | cc) & DIG_MASK; + cc = (a->p[i] & rm) >> (DIG_SIZE-n); } c.p[i] = cc; + trim(&c); mpz_set(mrb,c1,&c); mpz_clear(mrb,&c); } @@ -394,109 +403,61 @@ ulshift(mrb_state *mrb, mpz_t *c1, mpz_t *a, size_t n) static void udiv(mrb_state *mrb, mpz_t *qq, mpz_t *rr, mpz_t *xx, mpz_t *yy) { - mpz_t q, x, y, r; - int ns,f,ccc=0; - int xd,yd,i,j; - mp_limb zz,z,qhat,b,u,m; - - if (uzero(yy)) + /* simple cases */ + int cmp = ucmp(xx, yy); + if (cmp == 0) { + mpz_set_int(mrb, qq, 1); + zero(rr); + return; + } + else if (cmp < 0) { + zero(qq); + mpz_set(mrb, rr, yy); return; - mpz_init(mrb,&q); mpz_init(mrb,&x);mpz_init(mrb,&y);mpz_init(mrb,&r); - mpz_realloc(mrb,&x,(size_t)((xx->sz)+1)); - yd = digits(yy); - ns = lzb(yy->p[yd-1]); + } + + mpz_t q, x, y; + size_t i; + + if (uzero(yy)) return; /* divided by zero */ + mpz_init(mrb,&q); mpz_init(mrb,&x); mpz_init(mrb,&y); + mpz_realloc(mrb,&x,xx->sz+1); + size_t yd = digits(yy); + size_t ns = lzb(yy->p[yd-1]); ulshift(mrb,&x,xx,ns); ulshift(mrb,&y,yy,ns); - xd = digits(&x); - mpz_realloc(mrb,&q,(size_t)xd); - xd*=2; yd*=2; - z = hd(&y,yd-1); - for (j=(xd-yd);j>=0;j--) { - if (z == LMAX) - qhat = hd(&x,j+yd); - else { - qhat = ((hd(&x,j+yd)<< HALFDIGITBITS) + hd(&x,j+yd-1)) / (z+1); - } - b = 0; zz=0; + size_t xd = digits(&x); + mpz_realloc(mrb,&q,xd); + mp_limb2 z = y.p[yd-1]; + for (size_t j=(xd-yd);;j--) { + mp_limb2 qhat = (((mp_limb2)x.p[j+yd] << DIG_SIZE) + x.p[j+yd-1]) / z; + mp_limb2s b=0; if (qhat) { for (i=0; i=0; i--) { - if (hd(&x,j+i) > hd(&y,i)) { - f=1; - break; - } - if (hd(&x,j+i) < hd(&y,i)) { - f=0; - break; - } - } - } - if (!f) - break; - qhat++; - ccc++; - b=0; - for (i=0;isz)); - zero(&r); - urshift(mrb,&r,&x,ns); - mpz_set(mrb,rr,&r); + q.p[j] = qhat; + if (j == 0) break; + } + urshift(mrb,rr,&x,ns); + trim(&q); mpz_set(mrb,qq,&q); mpz_clear(mrb,&x); mpz_clear(mrb,&y); - mpz_clear(mrb,&q); mpz_clear(mrb,&r); + mpz_clear(mrb,&q); } static void @@ -616,8 +577,7 @@ static int mpz_sizeinbase(mpz_t *x, int base) { int i,j; - size_t bits = digits(x) * DIGITBITS; - + size_t bits = digits(x) * DIG_SIZE; mrb_assert(2 <= base && base <= 36); if (x->sz == 0) return 0; @@ -632,7 +592,7 @@ mpz_init_set_str(mrb_state *mrb, mpz_t *x, const char *s, mrb_int len, mrb_int b int retval = 0; mpz_t t,m,bb; short sn; - unsigned int k; + uint8_t k; mpz_init(mrb,x); mpz_init_set_int(mrb,&m,1); mpz_init(mrb,&t); @@ -645,15 +605,15 @@ mpz_init_set_str(mrb_state *mrb, mpz_t *x, const char *s, mrb_int len, mrb_int b } else sn = 1; - mpz_init_set_int(mrb,&bb, base); + mpz_init_set_int(mrb,&bb,base); for (mrb_int i = len-1; i>=0; i--) { if (s[i]=='_') continue; if (s[i] >= '0' && s[i] <= '9') - k = (unsigned int)s[i] - (unsigned int)'0'; + k = (uint8_t)s[i] - (uint8_t)'0'; else if (s[i] >= 'A' && s[i] <= 'Z') - k = (unsigned int)s[i] - (unsigned int)'A'+10; + k = (uint8_t)s[i] - (uint8_t)'A'+10; else if (s[i] >= 'a' && s[i] <= 'z') - k = (unsigned int)s[i] - (unsigned int)'a'+10; + k = (uint8_t)s[i] - (uint8_t)'a'+10; else { retval = (-1); break; @@ -666,8 +626,7 @@ mpz_init_set_str(mrb_state *mrb, mpz_t *x, const char *s, mrb_int len, mrb_int b mpz_add(mrb,x,x,&t); mpz_mul(mrb,&m,&m,&bb); } - if (x->sn) - x->sn = sn; + x->sn = sn; mpz_clear(mrb,&m); mpz_clear(mrb,&bb); mpz_clear(mrb,&t); @@ -691,23 +650,19 @@ mpz_get_str(mrb_state *mrb, char *s, mrb_int sz, mrb_int base, mpz_t *x) mp_limb *tend = t + xlen; memcpy(t, x->p, xlen*sizeof(mp_limb)); mp_limb b2 = base; - const int blim = (sizeof(mp_limb)==4)?(base<=10?4:3):(base<=10?9:5); + const int blim = (sizeof(mp_limb)<4)?(base<=10?4:3):(base<=10?9:5); for (int i=1; i= t) { - mp_limb d0 = *d, d1; - a = (a<sn < 0) { *s++ = '-'; @@ -747,42 +702,44 @@ while (psp + y->sz; - if (y->sn == 0) { - i = 0; + while (d-- > y->p) { + if (HIGH(i) != 0) { + /* will overflow */ + return FALSE; + } + i = (i << DIG_SIZE) | *d; } - else if ((d = digits(y)) > 2 || (d == 2 && y->p[1] > 1)) { + if (i > MRB_INT_MAX) { + /* overflow */ return FALSE; } - else if (d == 2) { - i = (y->sn * (y->p[0] | (y->p[1] & 1) << DIGITBITS)); + if (y->sn < 0) { + *v = -(mrb_int)i; } - else {/* d == 1 */ - i = y->sn * y->p[0]; + else { + *v = (mrb_int)i; } - if (MRB_INT_MAX < i || i < MRB_INT_MIN) return FALSE; - *v = i; return TRUE; } static void mpz_mul_2exp(mrb_state *mrb, mpz_t *z, mpz_t *x, mrb_int e) { - short sn = x->sn; if (e==0) mpz_set(mrb,z,x); else { - size_t i; - mp_limb digs = (e / DIGITBITS); - size_t bs = (e % (DIGITBITS)); + short sn = x->sn; + size_t digs = (e / DIG_SIZE); + size_t bs = (e % (DIG_SIZE)); mpz_t y; mpz_init(mrb, &y); - mpz_realloc(mrb, &y,(size_t)((x->sz)+digs)); - for (i=digs;i<((x->sz)+digs);i++) - (y.p)[i] = (x->p)[i - digs]; + mpz_realloc(mrb,&y,x->sz+digs); + for (size_t i=0;isz;i++) + y.p[i+digs] = x->p[i]; if (bs) { ulshift(mrb,z,&y,bs); } @@ -801,14 +758,13 @@ mpz_div_2exp(mrb_state *mrb, mpz_t *z, mpz_t *x, mrb_int e) if (e==0) mpz_set(mrb,z,x); else { - size_t i; - mp_limb digs = (e / DIGITBITS); - size_t bs = (e % (DIGITBITS)); + size_t digs = (e / DIG_SIZE); + size_t bs = (e % (DIG_SIZE)); mpz_t y; mpz_init(mrb,&y); - mpz_realloc(mrb,&y,(size_t)((x->sz) - digs)); - for (i=0; i < (x->sz - digs); i++) + mpz_realloc(mrb,&y,x->sz-digs); + for (size_t i=0; i < x->sz-digs; i++) (y.p)[i] = (x->p)[i+digs]; if (bs) { urshift(mrb,z,&y,bs); @@ -818,8 +774,9 @@ mpz_div_2exp(mrb_state *mrb, mpz_t *z, mpz_t *x, mrb_int e) } if (uzero(z)) z->sn = 0; - else + else { z->sn = sn; + } mpz_clear(mrb,&y); } } @@ -835,11 +792,11 @@ mpz_neg(mrb_state *mrb, mpz_t *x, mpz_t *y) static void mpz_and(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) /* not the most efficient way to do this */ { - size_t i,sz; - sz = imax(x->sz, y->sz); - mpz_realloc(mrb,z,(size_t)sz); - for (i=0; i < sz; i++) - (z->p)[i] = dg(x,i) & dg(y,i); + size_t sz = imin(x->sz, y->sz); + + mpz_realloc(mrb,z,sz); + for (size_t i=0; i < sz; i++) + (z->p)[i] = x->p[i] & y->p[i]; if (x->sn < 0 && y->sn < 0) z->sn = (-1); else @@ -851,9 +808,10 @@ mpz_and(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) /* not the most efficient static void mpz_or(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) /* not the most efficient way to do this */ { - size_t i,sz; - sz = imax(x->sz, y->sz); - mpz_realloc(mrb,z,(size_t)sz); + size_t i; + size_t sz = imax(x->sz, y->sz); + + mpz_realloc(mrb,z,sz); for (i=0; i < sz; i++) (z->p)[i] = dg(x,i) | dg(y,i); if (x->sn < 0 || y->sn < 0) @@ -867,9 +825,10 @@ mpz_or(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) /* not the most efficient static void mpz_xor(mrb_state *mrb, mpz_t *z, mpz_t *x, mpz_t *y) /* not the most efficient way to do this */ { - size_t i,sz; - sz = imax(x->sz, y->sz); - mpz_realloc(mrb,z,(size_t)sz); + size_t i; + + size_t sz = imax(x->sz, y->sz); + mpz_realloc(mrb,z,sz); for (i=0; i < sz; i++) (z->p)[i] = dg(x,i) ^ dg(y,i); if ((x->sn <= 0 && y->sn > 0) || (x->sn > 0 && y->sn <=0)) @@ -884,7 +843,7 @@ static void mpz_pow(mrb_state *mrb, mpz_t *zz, mpz_t *x, mrb_int e) { mpz_t t; - mp_ulimb mask = (((mp_ulimb)1)<< (LONGBITS-1)); + mrb_uint mask = 1ULL<<(sizeof(mrb_int)*8-1); if (e==0) { mpz_set_int(mrb, zz, 1L); @@ -1040,24 +999,25 @@ mrb_bint_new_float(mrb_state *mrb, mrb_float x) /* x should not be NaN nor Infinity */ mrb_assert(x == x && x != x * 0.5); + int sn; + if (x < 0.0) { + x = -x; + sn = -1; + } + else { + sn = 1; + } if (x < 1.0) { return mrb_fixnum_value(0); } struct RBigint *bint = bint_new(mrb); mpz_t *r = &bint->mp; + r->sn = sn; - if (x < 0.0) { - x = -x; - r->sn = -1; - } - else { - r->sn = 1; - } - - mrb_float b = (double)CMASK; + mrb_float b = (double)DIG_BASE; mrb_float bi = 1.0 / b; - size_t rn, i; + size_t rn; mp_limb *rp; mp_limb f; @@ -1066,8 +1026,8 @@ mrb_bint_new_float(mrb_state *mrb, mrb_float x) mpz_realloc(mrb, r, rn); rp = r->p; - for (i=rn-1;;i--) { - f = (mp_limb)x; + for (size_t i=rn-1;;i--) { + f = LOW((mp_limb)x); x -= f; mrb_assert(x < 1.0); rp[i] = f; @@ -1085,7 +1045,7 @@ mrb_bint_as_float(mrb_state *mrb, mrb_value self) mrb_float val = 0; while (d-- > i->p) { - val = val * (LMAX+1) + *d; + val = val * DIG_BASE + *d; } if (i->sn < 0) { diff --git a/mrbgems/mruby-bigint/core/bigint.h b/mrbgems/mruby-bigint/core/bigint.h index 52f0ceaf8b..24c29bda06 100644 --- a/mrbgems/mruby-bigint/core/bigint.h +++ b/mrbgems/mruby-bigint/core/bigint.h @@ -30,35 +30,16 @@ #include -#if defined(MRB_32BIT) && defined(MRB_INT32) -/* - * The values below are for 32 bit machines (i.e. machines with a - * 32 bit long type) - * You'll need to change them, if you're using something else - * If DIGITBITS is odd, see the comment at the top of mpz_sqrtrem - */ -typedef int32_t mp_limb; -typedef uint32_t mp_ulimb; -#define LMAX 0x3fffffffL -#define LC 0xc0000000L -#define CMASK (LMAX+1) -#define HLMAX 0x7fffL -#define HCMASK (HLMAX + 1) -#define HIGH(x) (((x) & 0x3fff8000L) >> 15) -#define LOW(x) ((x) & 0x7fffL) - +#ifdef MRB_NO_MPZ64BIT +typedef uint16_t mp_limb; +typedef uint32_t mp_limb2; +typedef int32_t mp_limb2s; #else -/* 64 bit long type */ -typedef int64_t mp_limb; -typedef uint64_t mp_ulimb; -#define LMAX 0x3fffffffffffffffLL -#define LC 0xc000000000000000LL -#define CMASK (LMAX+1) -#define HLMAX 0x7fffffffLL -#define HCMASK (HLMAX + 1) -#define HIGH(x) (((x) & 0x3fffffff80000000LL) >> 31) -#define LOW(x) ((x) & 0x7fffffffLL) +typedef uint32_t mp_limb; +typedef uint64_t mp_limb2; +typedef int64_t mp_limb2s; #endif +#define MPZ_DIG_SIZE (sizeof(mp_limb)*8) typedef struct _mpz_t { mp_limb *p; @@ -72,18 +53,6 @@ struct RBigint { }; #define RBIGINT(v) ((struct RBigint*)mrb_ptr(v)) -#define iabs(x) ((x>0) ? (x) : (-x)) -#define imax(x,y) ((x>y)?x:y) -#define LONGBITS (sizeof(mp_limb)*8) -#define DIGITBITS (LONGBITS-2) -#define HALFDIGITBITS ((LONGBITS-2)/2) - -#define hd(x,i) (((size_t)(i)>=2*((x)->sz))? 0:(((i)%2) ? HIGH((x)->p[(i)/2]) \ - : LOW((x)->p[(i)/2]))) -#define dg(x,i) (((size_t)(i) < (x)->sz) ? ((x)->p)[i] : 0) - -#define RBIGINT(v) ((struct RBigint*)mrb_ptr(v)) - mrb_static_assert_object_size(struct RBigint); #endif /* MRUBY_BIGINT_H */