This is big.c in view mode; [Download] [Up]
/* Copyright William F. Schelter 1991 Bignum routines. num_arith.c: add_int_big num_arith.c: big_minus num_arith.c: big_plus num_arith.c: big_quotient_remainder num_arith.c: big_sign num_arith.c: big_times num_arith.c: complement_big num_arith.c: copy_big num_arith.c: div_int_big num_arith.c: mul_int_big num_arith.c: normalize_big num_arith.c: normalize_big_to_object num_arith.c: stretch_big num_arith.c: sub_int_big num_comp.c: big_compare num_comp.c: big_sign num_log.c: big_sign num_log.c: copy_to_big num_log.c: normalize_big num_log.c: normalize_big_to_object num_log.c: stretch_big num_pred.c: big_sign number.c: big_to_double predicate.c: big_compare typespec.c: big_sign print.d: big_minus print.d: big_sign print.d: big_zerop print.d: copy_big print.d: div_int_big read.d: add_int_big read.d: big_to_double read.d: complement_big read.d: mul_int_big read.d: normalize_big read.d: normalize_big_to_object */ #define remainder gclremainder #define NEED_MP_H #include "include.h" #define BCOPY_BODY(x,y) \ do { int *ucop = (int *)(x); \ int *vcop = (int *) (y); \ {int j = lgef(ucop); \ while(--j >= 0) \ { *vcop++ = *ucop++;}}}while (0) bcopy_body(x,y) GEN x,y; {BCOPY_BODY(x,y);} /* coerce a pari GEN to a bignum or fixnum */ object make_integer(u) GEN u; { int l = lgef(u); if (l > (MP_CODE_WORDS+1) || ( l == (MP_CODE_WORDS+1) && (MP_ONLY_WORD(u) & (1<<31)) != 0 && (MP_ONLY_WORD(u) == ( 1<<31) ? signe(u) > 0 : 1))) { object ans ; GEN w; { BEGIN_NO_INTERRUPT; big_register_1->big.big_length = lg(u); big_register_1->big.big_self = u; ans = alloc_object(t_bignum); ans->big.big_self = 0; w = (plong *)alloc_relblock(lg(u)*sizeof(plong)); /* may have been relocated */ u = (GEN) big_register_1->big.big_self ; ans->big.big_self = w; ans->big.big_length = l; BCOPY_BODY(u , w); setlg(w,l); END_NO_INTERRUPT;} return ans; } else if (signe(u) > 0) return make_fixnum(MP_ONLY_WORD(u)); else if (signe(u) < 0) return make_fixnum(-MP_ONLY_WORD(u)); else return(small_fixnum(0)); } object make_bignum(u) GEN u; { BEGIN_NO_INTERRUPT; { object ans = alloc_object(t_bignum); GEN w; ans->big.big_length = lg(u); /* save u */ ans->big.big_self = u; w = (plong *)alloc_relblock(lg(u)*sizeof(plong)); /* restore u */ u = ans->big.big_self ; ans->big.big_self = w; BCOPY_BODY(u , ans->big.big_self); END_NO_INTERRUPT; return ans; }} big_zerop(x) object x; { return (signe(MP(x))== 0);} big_compare(x, y) object x,y; {return cmpii(MP(x),MP(y));} object big_minus(x) object x; { object y; setsigne(MP(x),-(signe(MP(x)))); y = make_integer(MP(x)); setsigne(MP(x),-(signe(MP(x)))); return y; } gcopy_to_big(res,x) GEN res; object x; {int l = (x)->big.big_length; int lgres = lg(res); if (l< lgres) { BEGIN_NO_INTERRUPT; big_register_1->big.big_length = lgres; big_register_1->big.big_self = res; (x)->big.big_self = (GEN) alloc_relblock(lgres*sizeof(int)); (x)->big.big_length = lgres; res = big_register_1->big.big_self ; END_NO_INTERRUPT; } BCOPY_BODY(res,(x)->big.big_self); if (l>lgres) { setlg((x)->big.big_self, l);} } add_int_big(i, x) int i; object x; { MPOP_DEST(x,addsi,i,MP(x)); } sub_int_big(i, x) int i; object x; { MPOP_DEST(x,subsi,i,MP(x)); } mul_int_big(i, x) int i; object x; { MPOP_DEST(x,mulsi,i,MP(x)); } /* Div_int_big(i, x) destructively divides non-negative bignum x by positive int i. X will hold the quotient from the division. Div_int_big(i, x) returns the remainder of the division. I should be positive. X should be non-negative. */ div_int_big(i, x) int i; object x; { save_avma; GEN res = divis(MP(x),i); gcopy_to_big(res,x); restore_avma; return hiremainder; } object big_plus(x, y) object x,y; { MPOP(return,addii,MP(x),MP(y)); } object big_times(x, y) object x,y; { MPOP(return,mulii,MP(x),MP(y)); } big_quotient_remainder(x0, y0, qp, rp) object x0,y0,*qp,*rp; { GEN res,quot; save_avma; res = dvmdii(MP(x0),MP(y0),"); *qp = make_integer(res); *rp = make_integer(quot); restore_avma; return; } double big_to_double(x) object x; { double d, e; GEN u = MP(x); unsigned int *w; int l; e = 4.294967296e9; l = lgef(u); MP_START_HIGH(w,(unsigned int *) u,l); l = l - MP_CODE_WORDS; if (l == 0) return 0.0; d = (double) MP_NEXT_DOWN(w); while (--l > 0) {d = e*d + (double)(MP_NEXT_DOWN(w));} if (signe(u)>0) return d; else return -d; } object normalize_big_to_object(x) object x; { return make_integer(MP(x));} object copy_big(x) object x; { if (type_of(x)==t_bignum) return make_bignum(MP(x)); else FEerror("bignum expected",0); } object copy_to_big(x) object x; {object y; if (type_of(x) == t_fixnum) { save_avma; y = make_bignum(stoi(fix(x))); restore_avma; } else if (type_of(x) == t_bignum) y = copy_big(x); else FEerror("integer expected",0); return(y); } /* return the power of x */ GEN powerii(x,y) GEN x, y; { GEN ans = gun; if (signe(y) < 0) FEerror("bad",0); while (lgef(y) > 2){ if (MP_LOW(y,lgef(y)) & 1) { ans = mulii(ans,x);} x = mulii(x,x); y = shifti(y,-1);} return ans; } replace_copy1(x,y) GEN y,x; { int j = lgef(x); if (y && j <= lg(y)) { x++; y++; while (--j >0) {*y++ = *x++;} return 0;} END: return j*2*sizeof(GEN); } /* doubles the length ! */ GEN replace_copy2(x,y) GEN y,x; {GEN yp = y; int k,j = lgef(x); k = j; while (--j >=0) {*yp++ = *x++;} y[0] = INT_FLAG + k*2; return y;} #define STOI(x,y) do{ \ if (x ==0) { y[1]=2;} \ else if((x)>0) {y[1]=0x1000003;y[2]=x;} \ else{y[1]=0xff000003;y[2]= -x;}}while (0) /* actually y == 0 is not supposed to happen !*/ obj_replace_copy1(x,y) object x; GEN y; { int j ; GEN xp; { if (type_of(x) == t_bignum) { j = lgef(MP(x)); if (y && j <= lg(y)) { xp=MP(x); xp++; y++; while (--j >0) {*y++ = *xp++;} return 0;}} else { if (y==0) return 3*2*sizeof(GEN) ; STOI(fix(x),y); return 0;}} END: return j*2*sizeof(GEN); } /* doubles the length ! */ GEN obj_replace_copy2(x,y) object x; GEN y; {GEN yp = y; GEN xp; int k,j; if (type_of(x) == t_bignum) { j = lgef(MP(x)); k = j; xp = MP(x); while (--j >=0) {*yp++ = *xp++;} y[0] = INT_FLAG + k*2;} else {STOI(fix(x),yp); y[0] = INT_FLAG+3*2;} return y;} GEN otoi(x) object x; {if (type_of(x)==t_fixnum) return stoi(fix(x)); if (type_of(x)==t_bignum) return (MP(x)); FEwrong_type_argument(sLinteger,x); return 0; } object alloc_bignum_static(len) int len; { object ans = alloc_object(t_bignum); GEN w; ans->big.big_length = len; ans->big.big_self = 0; w = (GEN)AR_ALLOC(alloc_contblock,len,unsigned plong); ans->big.big_self = w; w[0] = INT_FLAG + len; return ans; } GEN setq_io(x,all,val) GEN x; object val; object *all; {int n= obj_replace_copy1(val,x); if (n) { *all = alloc_bignum_static(n/sizeof(int)); return obj_replace_copy2(val,MP(*all)); } else return x;} GEN setq_ii(x,all,val) GEN x; GEN val; object *all; {int n= replace_copy1(val,x); if (n) { *all = alloc_bignum_static(n/sizeof(int)); return replace_copy2(val,MP(*all)); } else return x;} void isetq_fix(var,s) GEN var; int s; {/* if (var==0) FEerror("unitialized integer var",0); */ STOI(s,var); } GEN icopy_bignum(a,y) object a; GEN y; { int *ucop = (int *)MP(a); int *vcop = (int *) (y); int j = lgef(ucop); {while(--j >= 0) { *vcop++ = *ucop++;} setlg(y,a->big.big_length); return y;}} GEN icopy_fixnum(a,y) object a; GEN y; { int x= fix(a); if(!x) return gzero; y[0]=INT_FLAG+3; if(x>0) {y[1]=0x1000003;y[2]=x;} else{y[1]=0xff000003;y[2]= -x;} return y; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.