/* Division */ Rational bignum_div(Bignum _n, Bignum _m) { mpz_t n, m, tmp; *n = *theBIGNUM(_n); *m = *theBIGNUM(_m); mpz_init(tmp); mpz_mod(tmp, n, m); /* Divided evenly */ if (mpz_sgn(tmp) == 0) { mpz_cdiv_q(tmp, n, m); return make_bignum(tmp); } else { mpz_t q; ratio_t r; mpz_gcd(tmp, n, m); r = malloc(sizeof(struct ratio_t)); mpz_cdiv_q(q, n, tmp); r->numerator = make_bignum(q); mpz_cdiv_q(q, m, tmp); r->denominator = make_bignum(q); return make_ratio(r); } }
ScmObj Scm_MakeBignumFromUI(u_long val) { ScmBignum *b = make_bignum(1); b->sign = 1; b->values[0] = val; return SCM_OBJ(b); }
SCM SCM_FROM_TYPE_PROTO (TYPE val) { #if SIZEOF_TYPE != 0 && SIZEOF_TYPE < SIZEOF_SCM_T_BITS return SCM_I_MAKINUM (val); #else if (SCM_FIXABLE (val)) return SCM_I_MAKINUM (val); else if (val >= LONG_MIN && val <= LONG_MAX) return scm_i_long2big (val); else { SCM z = make_bignum (); mpz_init (SCM_I_BIG_MPZ (z)); if (val < 0) { val = -val; mpz_import (SCM_I_BIG_MPZ (z), 1, 1, sizeof (TYPE), 0, 0, &val); mpz_neg (SCM_I_BIG_MPZ (z), SCM_I_BIG_MPZ (z)); } else mpz_import (SCM_I_BIG_MPZ (z), 1, 1, sizeof (TYPE), 0, 0, &val); return z; } #endif }
ScmObj Scm_BignumCopy(const ScmBignum *b) { ScmBignum *c = make_bignum(b->size); c->sign = b->sign; for (u_int i=0; i<b->size; i++) c->values[i] = b->values[i]; return SCM_OBJ(c); }
/* Generators */ Bignum parse_bignum(char *token) { mpz_t x; mpz_init(x); mpz_set_str(x, token, 10); return make_bignum(x); }
scm_bignum_t make_bignum(object_heap_t* heap, scm_bignum_t bn) { int count = HDR_BIGNUM_COUNT(bn->hdr); scm_bignum_t obj = make_bignum(heap, count); obj->hdr = bn->hdr; memcpy(obj->elts, bn->elts, sizeof(digit_t) * count); return obj; }
ScmObj Scm_MakeBignumFromSI(long val) { ScmBignum *b; if (val == LONG_MIN) { b = make_bignum(1); b->sign = -1; b->values[0] = (unsigned long)LONG_MAX+1; } else if (val < 0) { b = make_bignum(1); b->sign = -1; b->values[0] = -val; } else { b = make_bignum(1); b->sign = 1; b->values[0] = val; } return SCM_OBJ(b); }
/* Convertors */ Bignum fixnum2bignum(Fixnum number) { mpz_t n; mpz_init(n); mpz_set_si(n, theFIXNUM(number)); return make_bignum(n); }
/* Subtraction */ DEFARIT(bignum_sub, Bignum) { mpz_t result; mpz_init(result); mpz_sub(result, theBIGNUM(n), theBIGNUM(m)); return make_bignum(result); }
object make_integer(__mpz_struct *u) { if ((u)->_mp_size == 0) return small_fixnum(0); if (mpz_fits_slong_p(u)) { return make_fixnum(mpz_get_si(u)); } return make_bignum(u); }
int main() { char *in_string; bignum *sum = make_bignum_with_length( 0 ); while( scanf( "%s", in_string ) != EOF ) { sum = add_bignums( make_bignum( in_string ), sum ); } print_bignum( sum ); }
/* If sign > 0 or sign < 0, values[] has absolute value. If sign == 0, values[] has 2's complement signed representation */ ScmObj Scm_MakeBignumFromUIArray(int sign, const u_long *values, int size) { ScmBignum *b = make_bignum(size); if (sign != 0) { b->sign = (sign > 0)? 1 : -1; for (int i=0; i<size; i++) b->values[i] = values[i]; } else { int nonzerop = FALSE; for (int i=0; i<size; i++) { if ((b->values[i] = values[i]) != 0) nonzerop = TRUE; } if (nonzerop) { if (values[size-1] <= LONG_MAX) b->sign = 1; else { b->sign = -1; bignum_2scmpl(b); } } else { b->sign = 0; } } return SCM_OBJ(b); }
void eval_e() { fracnum sum, term, tf; make_fracnum(1, 1, &term); make_fracnum(1, 1, &sum); bignum t, n; int i = 1; while(clock() < end_t1) { make_bignum(i++, &n); multiply(n, term.D, &t); copy(t, &term.D); add(sum, term, &tf); copy(tf, &sum); while(sum.N.len > 0 && sum.D.len > 0 && sum.N.d[sum.N.len-1] == 0 && sum.D.d[sum.D.len-1] == 0) sum.N.len--, sum.D.len--; } print(&sum); }
void make_fracnum(int N, int D, fracnum* f) { make_bignum(N, &(f->N)); make_bignum(D, &(f->D)); }