1
/* Copyright William F. Schelter 1991
6
num_arith.c: add_int_big
9
num_arith.c: big_quotient_remainder
11
num_arith.c: big_times
12
num_arith.c: complement_big
14
num_arith.c: div_int_big
15
num_arith.c: mul_int_big
16
num_arith.c: normalize_big
17
num_arith.c: normalize_big_to_object
18
num_arith.c: stretch_big
19
num_arith.c: sub_int_big
20
num_comp.c: big_compare
23
num_log.c: copy_to_big
24
num_log.c: normalize_big
25
num_log.c: normalize_big_to_object
26
num_log.c: stretch_big
28
number.c: big_to_double
29
predicate.c: big_compare
38
read.d: complement_big
41
read.d: normalize_big_to_object
45
#define BCOPY_BODY(x,y) \
46
do { int *ucop = (int *)(x); \
47
int *vcop = (int *) (y); \
48
{int j = lgef(ucop); \
50
{ *vcop++ = *ucop++;}}}while (0)
58
/* make a bignum with (most <<32 + least) */
63
= {0x01010004 ,0x01010004, 0,0};
66
if(most) {setlgef(u,4),l=4;}
67
else {l=3; setlgef(u,3);}
69
MP_NEXT_UP(w) = least;
70
if (most) MP_NEXT_UP(w) = most;
71
return make_integer(u);
76
/* coerce a pari GEN to a bignum or fixnum */
82
if (l > (MP_CODE_WORDS+1) ||
83
( l == (MP_CODE_WORDS+1) &&
84
(MP_ONLY_WORD(u) & (1<<31)) != 0
85
&& (MP_ONLY_WORD(u) == ( 1<<31) ? signe(u) > 0 : 1)))
90
big_register_1->big.big_length = lg(u);
91
big_register_1->big.big_self = u;
92
ans = alloc_object(t_bignum);
93
ans->big.big_self = 0;
94
w = (plong *)alloc_relblock(lg(u)*sizeof(plong));
95
/* may have been relocated */
96
u = (GEN) big_register_1->big.big_self ;
97
ans->big.big_self = w;
98
ans->big.big_length = l;
105
if (signe(u) > 0) return make_fixnum(MP_ONLY_WORD(u));
107
if (signe(u) < 0) return make_fixnum(-MP_ONLY_WORD(u));
109
return(small_fixnum(0));
116
{ BEGIN_NO_INTERRUPT;
117
{ object ans = alloc_object(t_bignum);
119
ans->big.big_length = lg(u);
121
ans->big.big_self = u;
122
w = (plong *)alloc_relblock(lg(u)*sizeof(plong));
124
u = ans->big.big_self ;
125
ans->big.big_self = w;
126
BCOPY_BODY(u , ans->big.big_self);
133
{ return (signe(MP(x))== 0);}
137
{return cmpii(MP(x),MP(y));}
143
setsigne(MP(x),-(signe(MP(x))));
144
y = make_integer(MP(x));
145
setsigne(MP(x),-(signe(MP(x))));
152
{int l = (x)->big.big_length;
155
{ BEGIN_NO_INTERRUPT;
156
big_register_1->big.big_length = lgres;
157
big_register_1->big.big_self = res;
158
(x)->big.big_self = (GEN) alloc_relblock(lgres*sizeof(int));
159
(x)->big.big_length = lgres;
160
res = big_register_1->big.big_self ;
163
BCOPY_BODY(res,(x)->big.big_self);
165
{ setlg((x)->big.big_self, l);}
173
MPOP_DEST(x,addsi,i,MP(x));
179
{ MPOP_DEST(x,subsi,i,MP(x));
185
{ MPOP_DEST(x,mulsi,i,MP(x));
189
Div_int_big(i, x) destructively divides non-negative bignum x
191
X will hold the quotient from the division.
192
Div_int_big(i, x) returns the remainder of the division.
193
I should be positive.
194
X should be non-negative.
201
GEN res = divis(MP(x),i);
211
{ MPOP(return,addii,MP(x),MP(y));
218
MPOP(return,mulii,MP(x),MP(y));
223
big_quotient_remainder(x0, y0, qp, rp)
224
object x0,y0,*qp,*rp;
228
res = dvmdii(MP(x0),MP(y0),");
229
*qp = make_integer(res);
230
*rp = make_integer(quot);
248
MP_START_HIGH(w,(unsigned int *) u,l);
249
l = l - MP_CODE_WORDS;
251
if (l == 0) return 0.0;
253
d = (double) MP_NEXT_DOWN(w);
255
{d = e*d + (double)(MP_NEXT_DOWN(w));}
256
if (signe(u)>0) return d;
262
normalize_big_to_object(x)
264
{ return make_integer(MP(x));}
270
if (type_of(x)==t_bignum)
271
return make_bignum(MP(x));
272
else FEerror("bignum expected",0);
282
if (type_of(x) == t_fixnum) {
284
y = make_bignum(stoi(fix(x)));
286
} else if (type_of(x) == t_bignum)
289
FEerror("integer expected",0);
294
/* return the power of x */
299
if (signe(y) < 0) FEerror("bad",0);
301
if (MP_LOW(y,lgef(y)) & 1)
302
{ ans = mulii(ans,x);}
319
return j*2*sizeof(GEN);
322
/* doubles the length ! */
331
y[0] = INT_FLAG + k*2;
334
#define STOI(x,y) do{ \
335
if (x ==0) { y[1]=2;} \
336
else if((x)>0) {y[1]=0x1000003;y[2]=x;} \
337
else{y[1]=0xff000003;y[2]= -x;}}while (0)
339
/* actually y == 0 is not supposed to happen !*/
341
obj_replace_copy1(x,y)
346
{ if (type_of(x) == t_bignum)
355
{ if (y==0) return 3*2*sizeof(GEN) ;
356
STOI(fix(x),y); return 0;}}
358
return j*2*sizeof(GEN);
361
/* doubles the length ! */
363
obj_replace_copy2(x,y)
369
if (type_of(x) == t_bignum)
375
y[0] = INT_FLAG + k*2;}
376
else {STOI(fix(x),yp); y[0] = INT_FLAG+3*2;}
383
{if (type_of(x)==t_fixnum) return stoi(fix(x));
384
if (type_of(x)==t_bignum)
386
FEwrong_type_argument(sLinteger,x);
391
alloc_bignum_static(len)
393
{ object ans = alloc_object(t_bignum);
395
ans->big.big_length = len;
396
ans->big.big_self = 0;
397
w = (GEN)AR_ALLOC(alloc_contblock,len,unsigned plong);
398
ans->big.big_self = w;
399
w[0] = INT_FLAG + len;
409
{int n= obj_replace_copy1(val,x);
411
{ *all = alloc_bignum_static(n/sizeof(int));
412
return obj_replace_copy2(val,MP(*all));
422
{int n= replace_copy1(val,x);
424
{ *all = alloc_bignum_static(n/sizeof(int));
425
return replace_copy2(val,MP(*all));
436
{/* if (var==0) FEerror("unitialized integer var",0); */
444
{ int *ucop = (int *)MP(a);
445
int *vcop = (int *) (y);
448
{ *vcop++ = *ucop++;}
449
setlg(y,a->big.big_length);
461
if(x>0) {y[1]=0x1000003;y[2]=x;}
462
else{y[1]=0xff000003;y[2]= -x;}
469
GEN gnil,gzero,gun,gdeux,ghalf,gi;
470
plong lontyp[30]={0,0x10000,0x10000,1,1,1,1,2,1,0,2,2,1,1,1,0,1,1,1,1};
471
unsigned plong hiremainder,overflow;
474
#define FEerror printf
475
#define make_si_sfun(a,b,c)
478
#define INITIAL_PARI_STACK 400
479
char initial_pari_stack[400];
481
our_ulong bot= (our_ulong) initial_pari_stack;
482
our_ulong top = (our_ulong)(initial_pari_stack+INITIAL_PARI_STACK);
492
FEerror("Out of bignum stack space, (si::MULTIPLY-BIGNUM-STACK n) to grow",0);
497
FEerror("Divide by zero",0);
499
FEerror("Multiply overflow",0);
501
FEerror("Mod by 0",0);
503
FEerror("Integer Arithmetic error",0);
509
multiply_bignum_stack(n)
511
{ int parisize = n* (top - bot);
514
{ if (bot != (our_ulong)initial_pari_stack) free(bot);
515
set_pari_stack(parisize);
520
set_pari_stack(parisize)
523
bot=(plong)malloc(parisize);
524
top = avma = bot + parisize;
527
/* things to be done every start */
537
make_si_sfun("MULTIPLY-BIGNUM-STACK",multiply_bignum_stack,
538
ARGTYPE1(f_fixnum) | RESTYPE(f_fixnum));
541
/* room for the permanent things */
543
gnil = cgeti(2);gnil[1]=2; setpere(gnil,255);
544
gzero = cgeti(2);gzero[1]=2; setpere(gzero, 255);
545
gun = stoi(1); setpere(gun, 255);
546
gdeux = stoi(2); setpere(gdeux, 255);
547
ghalf = cgetg(3,4);ghalf[1]=un;ghalf[2]=deux; setpere(ghalf, 255);
548
gi = cgetg(3,6); gi[1] = zero; gi[2] = un; setpere(gi, 255);
550
/* set_pari_stack(BIGNUM_STACK_SIZE);*/