00001
00002
00003
00004
00005
00006
00007
00008 static char *rcsid="@(#)$Id$";
00009
00010 #include "eus.h"
00011 #include <math.h>
00012 #if alpha
00013 #include <limits.h>
00014 #endif
00015 #if Cygwin
00016 #include <stdlib.h>
00017 #endif
00018 extern int ffsl(long int i);
00019
00020 extern pointer RANDSTATE;
00021 extern int gcd();
00022 extern pointer makeratio();
00023
00024 extern pointer copy_big(), big_plus(), big_minus();
00025 extern void sub_int_big(), add_int_big();
00026 extern pointer add_big_big(), big_times();
00027 extern pointer makebig(), makebig1(), makebig2(), extend_big(pointer,int);
00028 extern pointer normalize_bignum();
00029 extern eusfloat_t big_to_float(pointer);
00030 extern pointer eusfloat_to_big(float);
00031 extern eusinteger_t big_sign(pointer);
00032
00033
00034
00035
00036 pointer NUMEQUAL(ctx,n,argv)
00037 register context *ctx;
00038 register int n;
00039 register pointer argv[];
00040 { register eusfloat_t fx,fy;
00041 register pointer a,x;
00042 numunion nu;
00043
00044 if (n<=1) error(E_MISMATCHARG);
00045 x=argv[--n];
00046 if (isint(x)) {
00047 while (--n>=0) {
00048 a=argv[n];
00049 if (isflt(a)) { fx=intval(x); fy=fltval(a); goto flteqnum;}
00050 else if (isint(a)) { if (x!=a) return(NIL);}
00051 else if (pisratio(a)) { x=makeratio(intval(x),1); goto reqnum;}
00052 else if (pisbignum(a)) { return(NIL);}
00053 else error(E_NONUMBER);}
00054 return(T);}
00055 else if (isratio(x)) {
00056 while (--n>=0) {
00057 a=argv[n];
00058 if (isflt(a)) { fx=ratio2flt(x); fy=fltval(a); goto flteqnum;}
00059 else if (isint(a)) a=makeratio(intval(a),1);
00060 else if (!pisratio(a)) error(E_NONUMBER);
00061 reqnum:
00062 if ((a->c.ratio.numerator != x->c.ratio.numerator) ||
00063 (a->c.ratio.denominator != x->c.ratio.denominator))
00064 return(NIL);}
00065 return(T);}
00066 else if (isflt(x)) {
00067 fx=fltval(x);
00068 while (--n>=0) {
00069 fy=ckfltval(argv[n]);
00070 flteqnum:
00071 if (fx!=fy) return(NIL);}
00072 return(T); }
00073 else if (pisbignum(x))
00074 { eusinteger_t *xv, *av;
00075 int size,i;
00076 xv=bigvec(x); size=bigsize(x);
00077 while (--n >=0) {
00078 a=argv[n];
00079 if (!isbignum(a)) return(NIL);
00080 if (size != bigsize(a)) return(NIL);
00081 av=bigvec(a);
00082 for (i=0; i<size; i++) if (xv[i]!=av[i]) return(NIL);}
00083 return(T); }
00084 else error(E_NONUMBER);}
00085
00086 pointer NUMNEQUAL(ctx,n,argv)
00087 register context *ctx;
00088 register int n;
00089 register pointer argv[];
00090 { register int i;
00091 pointer cmparr[2];
00092 numunion nu;
00093
00094 if (n<=1) error(E_MISMATCHARG);
00095 while(--n>=0) {
00096 cmparr[0] = argv[n];
00097 for(i=0;i<n;++i){
00098 cmparr[1]=argv[i];
00099 if((NIL) != NUMEQUAL(ctx,2,cmparr))
00100 return(NIL);}}
00101 return(T);
00102 }
00103
00104 pointer GREATERP(ctx,n,argv)
00105 register context *ctx;
00106 register int n;
00107 register pointer argv[];
00108 { register pointer left,right;
00109 register eusfloat_t fleft,fright;
00110 eusinteger_t ival;
00111 eusinteger_t sign;
00112 int comparison;
00113 numunion nu;
00114
00115 if (n<=1) error(E_MISMATCHARG);
00116 right=argv[--n];
00117
00118 if (isint(right)) goto INTGT;
00119 else if (isflt(right)) goto FLTGT;
00120 else if (pisratio(right)) goto RATGT;
00121 else if (pisbignum(right)) goto BIGGT;
00122 else error(E_NONUMBER);
00123
00124 INTGT:
00125 while (--n>=0) {
00126 left=argv[n];
00127 if (isint(left)) {
00128 if ((eusinteger_t)left <= (eusinteger_t)right) return(NIL); }
00129 else if (isflt(left)) { fright=intval(right); goto fltgt2;}
00130 else if (isbignum(left)) {
00131 if (big_sign(left)<0) return(NIL);
00132 right=left; goto BIGGT; }
00133 if (!isint(left)) error(E_NONUMBER);
00134 right=left;}
00135 return(T);
00136
00137 BIGGT:
00138 sign=big_sign(right);
00139 while (--n>=0) {
00140 left=argv[n];
00141 if (isint(left)) {
00142 ival= intval(left);
00143 if (sign>=0) return(NIL);
00144 right=left;
00145 goto INTGT; }
00146 else if (isflt(left)) {
00147 fright=big_to_float(right);
00148 if (fltval(left)<=fright) return(NIL);
00149 goto FLTGT1;}
00150 else if (pisbignum(left)) {
00151 comparison=big_compare(left, right);
00152 if (comparison<=0) return(NIL);
00153 right=left;
00154 sign=big_sign(right);}
00155 else if (isratio(left)) goto RATGT; }
00156 FLTGT:
00157 fright=fltval(right);
00158 FLTGT1:
00159 while (--n>=0) {
00160 fltgt2: fleft=ckfltval(argv[n]);
00161 if (fleft<=fright) return(NIL);
00162 fright=fleft; }
00163 return(T);
00164 RATGT:
00165 error(E_USER,(pointer)"sorry, comparison of ratios are not yet implemented");
00166 }
00167
00168 pointer LESSP(ctx,n,argv)
00169 register context *ctx;
00170 register int n;
00171 register pointer argv[];
00172 { register pointer left,right;
00173 register eusfloat_t fleft,fright;
00174 eusinteger_t ival;
00175 eusinteger_t sign;
00176 int comparison;
00177 numunion nu;
00178
00179 if (n<=1) error(E_MISMATCHARG);
00180 right=argv[--n];
00181
00182 if (isint(right)) goto INTLT;
00183 else if (isflt(right)) goto FLTLT;
00184 else if (pisratio(right)) goto RATLT;
00185 else if (pisbignum(right)) goto BIGLT;
00186 else error(E_NONUMBER);
00187
00188 INTLT:
00189 while (--n>=0) {
00190 left=argv[n];
00191 if (isint(left)) {
00192 if ((eusinteger_t)left >= (eusinteger_t)right) return(NIL); }
00193 else if (isflt(left)) { fright=intval(right); goto FLTLT2;}
00194 else if (isbignum(left)) {
00195 if (big_sign(left)>0) return(NIL);
00196 right=left; goto BIGLT; }
00197 if (!isint(left)) error(E_NONUMBER);
00198 right=left;}
00199 return(T);
00200
00201 BIGLT:
00202 sign=big_sign(right);
00203 while (--n>=0) {
00204 left=argv[n];
00205 if (isint(left)) {
00206 ival= intval(left);
00207 if (sign<0) return(NIL);
00208 right=left;
00209 goto INTLT; }
00210 else if (isflt(left)) {
00211 fright=big_to_float(right);
00212 if (fltval(left)>=fright) return(NIL);
00213 goto FLTLT1;}
00214 else if (pisbignum(left)) {
00215 comparison=big_compare(left, right);
00216 if (comparison>=0) return(NIL);
00217 right=left;
00218 sign=big_sign(right);}
00219 else if (isratio(left)) goto RATLT; }
00220 FLTLT:
00221 fright=fltval(right);
00222 FLTLT1:
00223 while (--n>=0) {
00224 FLTLT2: fleft=ckfltval(argv[n]);
00225 if (fleft>=fright) return(NIL);
00226 fright=fleft; }
00227 return(T);
00228 RATLT:
00229 error(E_USER,(pointer)"sorry, comparison of ratios are not yet implemented");
00230 }
00231
00232 pointer GREQP(ctx,n,argv)
00233 register context *ctx;
00234 register int n;
00235 register pointer argv[];
00236 { register pointer left,right;
00237 register eusfloat_t fleft,fright;
00238 eusinteger_t ival;
00239 eusinteger_t sign;
00240 int comparison;
00241 numunion nu;
00242
00243 if (n<=1) error(E_MISMATCHARG);
00244 right=argv[--n];
00245
00246 if (isint(right)) goto INTGE;
00247 else if (isflt(right)) goto FLTGE;
00248 else if (pisratio(right)) goto RATGE;
00249 else if (pisbignum(right)) goto BIGGE;
00250 else error(E_NONUMBER);
00251
00252 INTGE:
00253 while (--n>=0) {
00254 left=argv[n];
00255 if (isint(left)) {
00256 if ((eusinteger_t)left < (eusinteger_t)right) return(NIL); }
00257 else if (isflt(left)) { fright=intval(right); goto FLTGE2;}
00258 else if (isbignum(left)) {
00259 if ((sign=big_sign(left))<0) return(NIL);
00260 right=left; goto BIGGE; }
00261 if (!isint(left)) error(E_NONUMBER);
00262 right=left;}
00263 return(T);
00264
00265 BIGGE:
00266 sign=big_sign(right);
00267 while (--n>=0) {
00268 left=argv[n];
00269 if (isint(left)) {
00270 ival= intval(left);
00271 if (sign>0) return(NIL);
00272 right=left;
00273 goto INTGE; }
00274 else if (isflt(left)) {
00275 fright=big_to_float(right);
00276 if (fltval(left)<fright) return(NIL);
00277 goto FLTGE1;}
00278 else if (pisbignum(left)) {
00279 comparison=big_compare(left, right);
00280 if (comparison<0) return(NIL);
00281 right=left;
00282 sign=big_sign(right);}
00283 else if (isratio(left)) goto RATGE; }
00284 FLTGE:
00285 fright=fltval(right);
00286 FLTGE1:
00287 while (--n>=0) {
00288 FLTGE2: fleft=ckfltval(argv[n]);
00289 if (fleft<fright) return(NIL);
00290 fright=fleft; }
00291 return(T);
00292 RATGE:
00293 error(E_USER,(pointer)"sorry, comparison of ratios are not yet implemented");
00294 }
00295
00296 pointer LSEQP(ctx,n,argv)
00297 register context *ctx;
00298 int n;
00299 pointer argv[];
00300 { register pointer left,right;
00301 register eusfloat_t fleft,fright;
00302 eusinteger_t ival;
00303 eusinteger_t sign;
00304 int comparison;
00305 numunion nu;
00306
00307 if (n<=1) error(E_MISMATCHARG);
00308 right=argv[--n];
00309
00310 if (isint(right)) goto INTLE;
00311 else if (isflt(right)) goto FLTLE;
00312 else if (pisratio(right)) goto RATLE;
00313 else if (pisbignum(right)) goto BIGLE;
00314 else error(E_NONUMBER);
00315
00316 INTLE:
00317 while (--n>=0) {
00318 left=argv[n];
00319 if (isint(left)) {
00320 if ((eusinteger_t)left > (eusinteger_t)right) return(NIL); }
00321 else if (isflt(left)) { fright=intval(right); goto FLTLE2;}
00322 else if (isbignum(left)) {
00323 if ((sign=big_sign(left))>0) return(NIL);
00324 right=left; goto BIGLE; }
00325 if (!isint(left)) error(E_NONUMBER);
00326 right=left;}
00327 return(T);
00328
00329 BIGLE:
00330 sign=big_sign(right);
00331 while (--n>=0) {
00332 left=argv[n];
00333 if (isint(left)) {
00334 ival= intval(left);
00335 if (sign<0) return(NIL);
00336 right=left;
00337 goto INTLE; }
00338 else if (isflt(left)) {
00339 fright=big_to_float(right);
00340 if (fltval(left) > fright) return(NIL);
00341 goto FLTLE1;}
00342 else if (pisbignum(left)) {
00343 comparison=big_compare(left, right);
00344 if (comparison > 0) return(NIL);
00345 right=left;
00346 sign=big_sign(right);}
00347 else if (isratio(left)) goto RATLE; }
00348 FLTLE:
00349 fright=fltval(right);
00350 FLTLE1:
00351 while (--n>=0) {
00352 FLTLE2: fleft=ckfltval(argv[n]);
00353 if (fleft > fright) return(NIL);
00354 fright=fleft; }
00355 return(T);
00356 RATLE:
00357 error(E_USER,(pointer)"sorry, comparison of ratios are not yet implemented");
00358 }
00359
00360 pointer MOD(ctx,n,argv)
00361 register context *ctx;
00362 int n;
00363 pointer argv[];
00364 { ckarg(2);
00365 if (isflt(argv[0]) || isflt(argv[1])) {
00366 numunion nu;
00367 register eusfloat_t x,y;
00368 x=ckfltval(argv[0]); y=ckfltval(argv[1]);
00369 return(makeflt(fmod(x,y)));
00370 } else {
00371 register eusinteger_t x,y;
00372 x=bigintval(argv[0]); y=bigintval(argv[1]);
00373 return(mkbigint(x % y));}}
00374
00375 pointer SUB1(ctx,n,argv)
00376 register context *ctx;
00377 int n;
00378 pointer argv[];
00379 { register pointer a=argv[0];
00380 eusfloat_t x;
00381 numunion nu;
00382
00383 ckarg(1);
00384 if (a==makeint(MINNEGFIXNUM)) { return(makebig1(MINNEGFIXNUM-1));}
00385 if (isint(a)) return((pointer)((eusinteger_t)a-4));
00386 else if (isflt(a)) {
00387 x=fltval(a);
00388 return(makeflt(x-1.0)); }
00389 else if (isbignum(a)) {
00390 a=copy_big(a); sub_int_big(1,a); return(normalize_bignum(a));}
00391 else error(E_NOINT);
00392 }
00393
00394
00395 pointer ADD1(ctx,n,argv)
00396 register context *ctx;
00397 int n;
00398 pointer argv[];
00399 { register pointer a=argv[0];
00400 eusfloat_t x;
00401 numunion nu;
00402
00403 ckarg(1);
00404 if (a==makeint(MAXPOSFIXNUM)) { return(makebig1(MAXPOSFIXNUM+1));}
00405 if (isint(a)) return((pointer)((eusinteger_t)a+4));
00406 else if (isflt(a)) {
00407 x=fltval(a);
00408 return(makeflt(x+1.0)); }
00409 else if (isbignum(a)) {
00410 a=copy_big(a); add_int_big(1,a); return(a);}
00411 else error(E_NOINT);
00412 }
00413
00414
00415
00416 pointer ratio_plus(x,y)
00417 pointer x,y;
00418 {
00419 register eusinteger_t x_num, x_den, y_num, y_den, z_num, z_den, d1,d2,t;
00420
00421 x_num = intval(x->c.ratio.numerator);
00422 x_den = intval(x->c.ratio.denominator);
00423 y_num = intval(y->c.ratio.numerator);
00424 y_den = intval(y->c.ratio.denominator);
00425
00426 d1=gcd(x_den,y_den);
00427 if(d1 == 1){
00428 z_num = x_num * y_den + x_den * y_num;
00429 z_den = x_den * y_den;
00430 return(makeratio(z_num,z_den));}
00431 else{
00432 t = x_num * (y_den / d1) + y_num * (x_den / d1);
00433 d2=gcd(t,d1);
00434
00435 z_num = t / d2;
00436 z_den = (x_den / d1) * (y_den / d2);
00437 return(makeratio(z_num,z_den));}
00438 }
00439
00440 pointer ratio_minus(x,y)
00441 pointer x,y;
00442 {
00443 register eusinteger_t x_num,x_den,y_num,y_den,z_num,z_den,d1,d2,t;
00444
00445 x_num = intval(x->c.ratio.numerator);
00446 x_den = intval(x->c.ratio.denominator);
00447 y_num = intval(y->c.ratio.numerator);
00448 y_den = intval(y->c.ratio.denominator);
00449 d1 = gcd(x_den,y_den);
00450 if(d1 == 1){
00451 z_num = x_num * y_den - x_den * y_num;
00452 z_den = x_den * y_den;
00453 return(makeratio(z_num,z_den));}
00454 else{
00455 t = x_num * (y_den / d1) - y_num * (x_den / d1);
00456 d2=gcd(t,d1);
00457 z_num = t / d2;
00458 z_den = (x_den / d1) * (y_den / d2);
00459 return(makeratio(z_num,z_den));}
00460 }
00461
00462 pointer ratio_times(x,y)
00463 pointer x,y;
00464 {
00465 register eusinteger_t x_num,x_den,y_num,y_den,z_num,z_den,d1,d2;
00466
00467 x_num = intval(x->c.ratio.numerator);
00468 x_den = intval(x->c.ratio.denominator);
00469 y_num = intval(y->c.ratio.numerator);
00470 y_den = intval(y->c.ratio.denominator);
00471 d1=gcd(x_num,y_den);
00472 d2=gcd(x_den,y_num);
00473
00474 z_num = (x_num / d1) * (y_num / d2);
00475 z_den = (x_den / d2) * (y_den / d1);
00476
00477 return(makeratio(z_num,z_den));
00478 }
00479
00480 pointer ratio_divide(x,y)
00481 pointer x,y;
00482 {
00483 register eusinteger_t x_num,x_den,y_num,y_den,z_num,z_den,d1,d2;
00484 register int sign;
00485
00486 x_num = intval(x->c.ratio.numerator);
00487 x_den = intval(x->c.ratio.denominator);
00488 y_num = intval(y->c.ratio.numerator);
00489 y_den = intval(y->c.ratio.denominator);
00490
00491 d1=gcd(x_num,y_num);
00492 d2=gcd(x_den,y_den);
00493
00494 if(y_num >= 0) sign=1; else sign=-1;
00495
00496 z_num = (x_num / d1) * (y_den / d2) * sign;
00497 z_den = abs((x_den / d2) * (y_num / d1));
00498
00499 return(makeratio(z_num,z_den));
00500 }
00501
00502 pointer int2ratio(i)
00503 eusinteger_t i;
00504 { return(makeratio(i,1));}
00505
00506 eusfloat_t ratio2flt(r)
00507 pointer r;
00508 { pointer p,q;
00509 eusfloat_t num, den;
00510 p=r->c.ratio.numerator;
00511 q=r->c.ratio.denominator;
00512 if (isint(p)) num=intval(p);
00513 else if (isbignum(p)) num=big_to_float(p);
00514 else error(E_USER,(pointer)"illegal ratio numerator");
00515
00516 if (isint(q)) den=intval(q);
00517 else if (isbignum(q)) den=big_to_float(q);
00518 else error(E_USER,(pointer)"illegal ratio denominator");
00519
00520 return(num/den);}
00521
00522 pointer return_ratio(r)
00523 pointer r;
00524 { if (intval(r->c.ratio.numerator)==0) return(makeint(0));
00525 else if (intval(r->c.ratio.denominator)==1) return(r->c.ratio.numerator);
00526 else return(r);}
00527
00528
00529 pointer PLUS(ctx,n,argv)
00530 register context *ctx;
00531 register int n;
00532 register pointer argv[];
00533 { eusfloat_t fs;
00534 register eusinteger_t is=0,j;
00535 register int i=0;
00536 register pointer a, r, rs;
00537 pointer b;
00538 numunion nu;
00539
00540 while (i<n) {
00541 a=argv[i];
00542 if (isint(a)) {
00543 j=intval(a);
00544 is+=j;
00545 if (((is >> 1) ^ is)&((eusinteger_t)1<<(WORD_SIZE-3))) {
00546 b=makebig1(0); goto bigplus;} }
00547 else if (isflt(a)) { fs=is; goto fplus;}
00548 else if (pisratio(a)) { rs=makeratio(is,1); goto rplus;}
00549 else if (pisbignum(a)) { b=copy_big(a); goto bigplus;}
00550 else error(E_NONUMBER);
00551 i++;}
00552 return(makeint(is));
00553 rplus:
00554 while (i<n) {
00555 a=argv[i];
00556 if (isint(a)) a=makeratio(intval(a),1);
00557 else if (isflt(a)) { fs=ratio2flt(rs); goto fplus;}
00558 else if (!isratio(a)) error(E_NONUMBER);
00559 rs= ratio_plus(rs, a);
00560 i++;}
00561 return(return_ratio(rs));
00562 fplus:
00563 while (i<n) {
00564 fs+=ckfltval(argv[i]);
00565 i++;}
00566 return(makeflt(fs));
00567 bigplus:
00568
00569 i++;
00570 if (is >= 0) add_int_big(is, b);
00571 else sub_int_big(-is, b);
00572 vpush(b);
00573 while (i<n) {
00574 a=argv[i];
00575 if (isint(a)) {
00576 j=intval(a);
00577 if (j>0) add_int_big(j,b);
00578 else if (j<0) sub_int_big(-j,b);
00579 b=normalize_bignum(b);}
00580 else if (isbignum(a)) {
00581 b=big_plus(a,b);
00582 vpop();
00583 vpush(b);
00584 b=normalize_bignum(b);
00585 }
00586 i++; }
00587 vpop();
00588 return(b);
00589 }
00590
00591 pointer MINUS(ctx,n,argv)
00592 register context *ctx;
00593 register int n;
00594 register pointer argv[];
00595 { eusfloat_t fs;
00596 register eusinteger_t is,ia;
00597 register int i;
00598 register pointer a=argv[0], rs, b, z;
00599 numunion nu;
00600
00601 if (n<1) error(E_MISMATCHARG);
00602 else if (n==1) {
00603 if (a==makeint(MINNEGFIXNUM)) return(makebig1(-MINNEGFIXNUM));
00604 if (isint(a)) return(makeint(-intval(a)));
00605 else if (isflt(a)) {
00606 fs= -fltval(a);
00607 return(makeflt(fs));}
00608 else if (isratio(a)) {
00609 return(makeratio(-intval(a->c.ratio.numerator),
00610 intval(a->c.ratio.denominator)));}
00611
00612 else if (isbignum(a)) { return(normalize_bignum(big_minus(a)));}
00613 else error(E_NONUMBER); }
00614
00615
00616
00617 i=1;
00618
00619 if (isint(a)) { is=intval(a); goto IMINUS;}
00620 else if (isflt(a)) { fs=fltval(a); goto FMINUS;}
00621 else if (pisratio(a)) { rs=a; goto RMINUS;}
00622 else if (isbignum(a)) { b=copy_big(a); goto BIGMINUS;}
00623 else error(E_NONUMBER);
00624
00625 IMINUS:
00626 while (i<n) {
00627 a=argv[i++];
00628 if (isint(a)) {
00629 is -= intval(a);
00630 if (((is >> 1) ^ is)&((eusinteger_t)1<<(WORD_SIZE-3))) {
00631 b=makebig1(is); goto BIGMINUS;} }
00632 else if (isflt(a)) { fs=is; goto FMINUS1;}
00633 else if (pisratio(a)) { rs=makeratio(is,1); goto RMINUS1;}
00634 else if (isbignum(a)) {
00635 z=big_minus(a);
00636 vpush(z);
00637 if (is>0) add_int_big(is, z);
00638 else if (is<0) sub_int_big(-is, z);
00639 z=normalize_bignum(z);
00640 if (isint(z)) { vpop(); is= intval(z);}
00641 else { b=z; goto BIGMINUS1;} }
00642 else error(E_NONUMBER); }
00643 return(makeint(is));
00644
00645 RMINUS:
00646 while (i<n) {
00647 a=argv[i++];
00648 RMINUS1:
00649 if (isint(a)) a=makeratio(intval(a),1);
00650 else if (isflt(a)) { fs=ratio2flt(rs); goto FMINUS;}
00651 else if (!isratio(a)) error(E_NONUMBER);
00652 rs= ratio_minus(rs, a);
00653 }
00654 return(return_ratio(rs));
00655
00656 FMINUS:
00657 while (i<n) {
00658 a=argv[i++];
00659 FMINUS1:
00660 fs -= ckfltval(a); }
00661 return(makeflt(fs));
00662
00663 BIGMINUS:
00664 vpush(b);
00665 BIGMINUS1:
00666 while (i<n) {
00667 a=argv[i++];
00668 if (isint(a)) {
00669 ia=intval(a);
00670 if (ia>0) sub_int_big(intval(a), b);
00671 else if (ia<0) add_int_big(-ia, b);
00672 b=normalize_bignum(b);
00673 if (isint(b)) { vpop(); is=intval(b); goto IMINUS;}
00674 }
00675 else if (isflt(a)) {
00676 is= big_to_float(b); vpop(); goto FMINUS;}
00677 else if (isbignum(a)) {
00678 z= big_minus(a);
00679 vpush(z);
00680 b=big_plus(b,z);
00681 ctx->vsp[-2]=b;
00682 vpop();
00683 b=normalize_bignum(b);
00684 if (isint(b)) { vpop(); is=intval(b); goto IMINUS;}
00685 }
00686 else if (isratio(a)) error(E_USER,(pointer)"BIG-RATIO not supported");
00687 else error(E_NONUMBER);}
00688 return(b);}
00689
00690 pointer TIMES(ctx,n,argv)
00691 register context *ctx;
00692 register int n;
00693 register pointer argv[];
00694 { register eusfloat_t fs;
00695 register eusinteger_t is,s;
00696 register int i;
00697 register eusinteger_t sign=1;
00698 register pointer a, rs, b;
00699 eusinteger_t hi, lo;
00700 numunion nu;
00701
00702
00703
00704
00705
00706 i=1;
00707 a=argv[0];
00708 if (isint(a)) { is=intval(a); goto ITIMES;}
00709 else if (isflt(a)) { fs=fltval(a); goto FTIMES;}
00710 else if (isratio(a)) { rs=a; vpush(rs); goto RTIMES;}
00711 else if (isbignum(a)) { b=copy_big(a); vpush(b); goto BIGTIMES;}
00712 else error(E_NONUMBER);
00713
00714 ITIMES:
00715 while (i<n) {
00716 a=argv[i++];
00717 ITIMES1:
00718
00719 if (isint(a)) {
00720 s=intval(a);
00721 if (s==0 || is==0) { is=0; break;}
00722 if (is<0) { sign= -1; is = -is;}
00723 if (s<0) { sign= -sign; s = -s;}
00724 extended_mul(is, s, 0, &hi, &lo);
00725 if( hi !=0 || (lo & ((eusinteger_t)7 << (WORD_SIZE-3)))!=0) {
00726 b=makebig2(hi, lo & MASK);
00727 b=normalize_bignum(b);
00728 vpush(b);
00729 if (sign<0) complement_big(b);
00730 goto BIGTIMES;}
00731 else is= lo*sign;}
00732 else if (isflt(a)) { fs=is; goto FTIMES1;}
00733 else if (pisbignum(a)) {
00734 b=copy_big(a);
00735 vpush(b);
00736 goto BIGTIMES1;}
00737 else if (pisratio(a)) {
00738 rs=makeratio(is,1);
00739 vpush(rs);
00740 goto RTIMES1;}
00741 else error(E_NONUMBER);}
00742 return(makeint(is));
00743
00744 RTIMES:
00745 while (i<n) {
00746 a=argv[i++];
00747 RTIMES1:
00748 if (isint(a)) a=makeratio(intval(a),1);
00749 else if (isflt(a)) { fs=ratio2flt(rs); goto FTIMES1;}
00750 else if (!isratio(a)) error(E_NONUMBER);
00751 rs= ratio_times(rs, a);
00752 ctx->vsp[-1]=rs;
00753 }
00754 ctx->lastalloc=rs;
00755 vpop();
00756 return(return_ratio(rs));
00757
00758 BIGTIMES:
00759 while (i<n) {
00760 a=argv[i++];
00761 if (isint(a)) {
00762 is=intval(a);
00763 BIGTIMES1:
00764
00765 sign=big_sign(b);
00766 if (sign<0) { complement_big(b);}
00767 if (is<0) { sign = -sign; is= -is;}
00768 mul_int_big(is, b);
00769 if (sign<0) complement_big(b);
00770 b=normalize_bignum(b);
00771 if (isint(b)) { is=intval(b); vpop(); goto ITIMES;}
00772 }
00773 else if (isflt(a)) {
00774 fs = big_to_float(b); vpop(); goto FTIMES1;}
00775 else if (pisbignum(a)) {
00776 sign=big_sign(b);
00777 if (sign<0) complement_big(b);
00778 if (big_sign(a)<0) { sign= -sign; a=big_minus(a);}
00779 vpush(a);
00780 b=big_times(a,b);
00781 ctx->vsp[-2]=b;
00782 vpop();
00783 b=normalize_bignum(b);
00784 if (isint(b)) { is=intval(b); vpop(); goto ITIMES;}
00785 }
00786 else if (pisratio(a)) {
00787 error(E_USER,(pointer)"sorry, big * ratio is not yet implemented.");}
00788 else error(E_NONUMBER);
00789 }
00790 ctx->lastalloc= vpop();
00791 return(b);
00792
00793 FTIMES:
00794 while (i<n) {
00795 a=argv[i++];
00796 FTIMES1:
00797 fs*=ckfltval(a);}
00798 return(makeflt(fs));}
00799
00800 pointer QUOTIENT(ctx, n,argv)
00801 register context *ctx;
00802 register int n;
00803 pointer argv[];
00804 { register eusfloat_t fs;
00805 register eusinteger_t is;
00806 register int i=1;
00807 register pointer a, rs;
00808 numunion nu;
00809 int sign;
00810
00811 if (n<1) error(E_MISMATCHARG);
00812 a=argv[0];
00813 if (isint(a)) is=intval(a);
00814 else if (isflt(a)) { fs=fltval(a); goto fquo;}
00815 else if (pisratio(a)) {rs=a; goto rquo;}
00816 else if (pisbignum(a)) { rs=copy_big(a); goto bquo;}
00817 else error(E_NONUMBER);
00818
00819 if (n==1) {
00820 fs=fltval(a);
00821 return(makeflt(1.0/fs));}
00822
00823 while (i<n) {
00824 a=argv[i];
00825 if (isflt(a)) { fs=is; goto fquo2;}
00826 else if (isint(a)) is/=intval(a);
00827 else if (pisratio(a)) { rs=makeratio(is,1); goto rquo;}
00828 else if (pisbignum(a)) is = 0;
00829 else error(E_NONUMBER);
00830 i++;}
00831 return(makeint(is));
00832
00833 rquo:
00834 while (i<n) {
00835 a=argv[i];
00836 if (isint(a)) a=makeratio(intval(a),1);
00837 else if (isflt(a)) { fs=ratio2flt(rs); goto fquo;}
00838 else if (!isratio(a)) error(E_NONUMBER);
00839 rs= ratio_divide(rs, a);
00840 i++;}
00841 return(return_ratio(rs));
00842 fquo:
00843 if (n==1) return(makeflt(1.0/fs));
00844 fquo2:
00845 while (i<n) {
00846 a=argv[i];
00847 fs/=ckfltval(a);
00848 i++;}
00849 return(makeflt(fs));
00850
00851 bquo:
00852 if (big_sign(rs)<0) { sign= -1; complement_big(rs);}
00853 else sign=1;
00854 while (i<n) {
00855 a=argv[i];
00856 if (isflt(a)) {
00857 fs=sign*big_to_float(rs); goto fquo2;}
00858 if (!isint(a)) {
00859 int rv = sign*div_big_big(a, rs);
00860 return(mkbigint(rv));
00861 } else {
00862 is=intval(a);
00863 if (is<0) { sign = - sign; is= -is;}
00864 div_int_big(is, rs);
00865 }
00866 i++;
00867 }
00868 if (sign<0) complement_big(rs);
00869 return(normalize_bignum(rs));
00870 }
00871
00872
00873
00874
00875 pointer SIN(ctx,n,argv)
00876 register context *ctx;
00877 int n;
00878 pointer argv[];
00879 { numunion nu;
00880 ckarg(1);
00881 return(makeflt(sin(ckfltval(argv[0]))));}
00882
00883 pointer COS(ctx,n,argv)
00884 register context *ctx;
00885 int n;
00886 pointer argv[];
00887 { numunion nu;
00888 ckarg(1);
00889 return(makeflt(cos(ckfltval(argv[0]))));}
00890
00891 pointer TAN(ctx,n,argv)
00892 register context *ctx;
00893 int n;
00894 pointer argv[];
00895 { numunion nu;
00896 ckarg(1);
00897 return(makeflt(tan(ckfltval(argv[0]))));}
00898
00899 pointer ATAN(ctx,n,argv)
00900 register context *ctx;
00901 int n;
00902 pointer argv[];
00903 { numunion nu;
00904 if (n==1) return(makeflt(atan(ckfltval(argv[0]))));
00905 else if (n==2) return(makeflt(atan2(ckfltval(argv[0]),ckfltval(argv[1]))));
00906 else error(E_MISMATCHARG);}
00907
00908 pointer TANH(ctx,n,argv)
00909 register context *ctx;
00910 int n;
00911 pointer argv[];
00912 { numunion nu;
00913 ckarg(1);
00914 return(makeflt(tanh(ckfltval(argv[0]))));}
00915
00916 pointer ATANH(ctx,n,argv)
00917 register context *ctx;
00918 int n;
00919 pointer argv[];
00920 { numunion nu;
00921 ckarg(1);
00922 return(makeflt(atanh(ckfltval(argv[0]))));}
00923
00924 pointer SINH(ctx,n,argv)
00925 register context *ctx;
00926 int n;
00927 pointer argv[];
00928 { numunion nu;
00929 ckarg(1);
00930 return(makeflt(sinh(ckfltval(argv[0]))));}
00931
00932 pointer ASINH(ctx,n,argv)
00933 register context *ctx;
00934 int n;
00935 pointer argv[];
00936 { numunion nu;
00937 ckarg(1);
00938 return(makeflt(asinh(ckfltval(argv[0]))));}
00939
00940 pointer COSH(ctx,n,argv)
00941 register context *ctx;
00942 int n;
00943 pointer argv[];
00944 { numunion nu;
00945 ckarg(1);
00946 return(makeflt(cosh(ckfltval(argv[0]))));}
00947
00948 pointer ACOSH(ctx,n,argv)
00949 register context *ctx;
00950 int n;
00951 pointer argv[];
00952 { numunion nu;
00953 ckarg(1);
00954 return(makeflt(acosh(ckfltval(argv[0]))));}
00955
00956 pointer SQRT(ctx,n,argv)
00957 register context *ctx;
00958 int n;
00959 pointer argv[];
00960 { numunion nu;
00961 ckarg(1);
00962 return(makeflt(sqrt(ckfltval(argv[0]))));}
00963
00964 pointer LOG(ctx,n,argv)
00965 register context *ctx;
00966 int n;
00967 pointer argv[];
00968 { double a;
00969 numunion nu;
00970 a=log(ckfltval(argv[0]));
00971 if (n==1) return(makeflt(a));
00972 else if (n==2) return(makeflt(a/log(ckfltval(argv[1]))));
00973 else error(E_MISMATCHARG);}
00974
00975 pointer EXP(ctx,n,argv)
00976 register context *ctx;
00977 int n;
00978 pointer argv[];
00979 { numunion nu;
00980 ckarg(1);
00981 return(makeflt(exp(ckfltval(argv[0]))));}
00982
00983 pointer ABS(ctx,n,argv)
00984 register context *ctx;
00985 int n;
00986 register pointer argv[];
00987 { register pointer a, b;
00988 eusfloat_t fa;
00989 numunion nu;
00990 ckarg(1);
00991 a=argv[0];
00992 if (a==makeint(MINNEGFIXNUM)) return(makebig1(-MINNEGFIXNUM));
00993 if (isint(a)) return(makeint(labs(intval(a))));
00994 else if (isflt(a)) return(makeflt(fabs(fltval(a))));
00995 else if (pisbignum(a)) {
00996 if (big_sign(a)<0) {
00997 b=copy_big(a);
00998 complement_big(b);
00999 return(b);}
01000 else return(a);}
01001 else error(E_NONUMBER);}
01002
01003 pointer ROUND(ctx,n,argv)
01004 register context *ctx;
01005 int n;
01006 register pointer argv[];
01007 { register pointer a=argv[0];
01008 eusfloat_t f;
01009 register eusinteger_t x;
01010 numunion nu;
01011 ckarg(1);
01012 if (isint(a)) return(a);
01013 else if (isbignum(a)) return(a);
01014 else {
01015 f=ckfltval(a);
01016 f=(double)rint(f);
01017 return(eusfloat_to_big(f));}
01018 }
01019
01020 pointer FLOOR(ctx,n,argv)
01021 register context *ctx;
01022 int n;
01023 pointer argv[];
01024 { register pointer a=argv[0];
01025 eusfloat_t f;
01026 register eusinteger_t x;
01027 numunion nu;
01028 ckarg(1);
01029 if (isint(a)) return(a);
01030 else if (isbignum(a)) return(a);
01031 else {
01032 f=floor(ckfltval(a)); return(eusfloat_to_big(f));} }
01033
01034 pointer CEILING(ctx,n,argv)
01035 register context *ctx;
01036 int n;
01037 pointer argv[];
01038 { register pointer a=argv[0];
01039 eusfloat_t f;
01040 numunion nu;
01041 ckarg(1);
01042 if (isint(a)) return(a);
01043 else if (isbignum(a)) return(a);
01044 else { f=ckfltval(a); f=ceil(f); return(eusfloat_to_big(f));}
01045 }
01046
01047 pointer TRUNCATE(ctx,n,argv)
01048 register context *ctx;
01049 int n;
01050 pointer argv[];
01051 { register pointer a=argv[0];
01052 eusfloat_t f;
01053 register eusinteger_t x;
01054 numunion nu;
01055 ckarg(1);
01056 if (isint(a)) return(a);
01057 else if (isbignum(a)) return(a);
01058 else { f=ckfltval(a); return(eusfloat_to_big(f));}
01059 }
01060
01061 pointer FREXP(ctx,n,argv)
01062 context *ctx;
01063 int n;
01064 pointer argv[];
01065 { eusfloat_t f,z;
01066 int exp;
01067 pointer p;
01068 numunion nu;
01069 extern double frexp(double, int *);
01070 ckarg(1);
01071 f=ckfltval(argv[0]);
01072 z=frexp(f, &exp);
01073 p=cons(ctx, makeint(exp), NIL);
01074 return(cons(ctx,makeflt(z),p));
01075 }
01076
01077 pointer EUSFLOAT(ctx,n,argv)
01078 register context *ctx;
01079 int n;
01080 pointer argv[];
01081 { pointer a;
01082 eusfloat_t f;
01083 numunion nu;
01084 ckarg(1);
01085 a=argv[0];
01086 if (isflt(a)) return(a);
01087 else if (isint(a)) { f=intval(a); return(makeflt(f));}
01088 else { f=ckfltval(a); return(makeflt(f));}
01089 }
01090
01091 pointer DECFLOAT(ctx,n,argv)
01092 register context *ctx;
01093 int n;
01094 pointer argv[];
01095 { pointer x;
01096 eusinteger_t i;
01097 ckarg(1);
01098 x=argv[0];
01099 if (!isflt(x)) error(E_NONUMBER);
01100 i=intval(x);
01101 return(makeint(i));}
01102
01103 pointer MAX(ctx,n,argv)
01104 register context *ctx;
01105 register int n;
01106 pointer argv[];
01107 { eusfloat_t fs,fm;
01108 register int i=1;
01109 register eusinteger_t is;
01110 register pointer a=argv[0];
01111 numunion nu;
01112 if (n<1) error(E_MISMATCHARG);
01113 if (n==1) return(a);
01114 if (isint(a)) is=(eusinteger_t)a;
01115 else { fs=ckfltval(a); goto fmax; }
01116 while (i<n) {
01117 a=argv[i];
01118 if (isint(a)) { if (is<(eusinteger_t)a) is=(eusinteger_t)a;}
01119 else { fs=intval((pointer)is); goto fmax; }
01120 i++;}
01121 return((pointer)is);
01122 fmax:
01123 while (i<n) {
01124 fm=ckfltval(argv[i]);
01125 if (fs<fm) fs=fm;
01126 i++;}
01127 return(makeflt(fs));}
01128
01129 pointer MIN(ctx,n,argv)
01130 register context *ctx;
01131 register int n;
01132 register pointer argv[];
01133 { eusfloat_t fs,fm;
01134 register int i=1;
01135 register eusinteger_t is;
01136 register pointer a=argv[0];
01137 numunion nu;
01138 if (n<1) error(E_MISMATCHARG);
01139 if (n==1) return(a);
01140 if (isint(a)) is=(eusinteger_t)a;
01141 else { fs=ckfltval(a); goto fmin;}
01142 while (i<n) {
01143 a=argv[i];
01144 if (isint(a)) { if (is>(eusinteger_t)a) is=(eusinteger_t)a;}
01145 else { fs=intval((pointer)is); goto fmin;}
01146 i++;}
01147 return((pointer)is);
01148 fmin:
01149 while (i<n) {
01150 fm=ckfltval(argv[i]);
01151 if (fs>fm) fs=fm;
01152 i++;}
01153 return(makeflt(fs));}
01154
01155
01156
01157
01158 pointer LOGAND(context *ctx, int n, pointer argv[])
01159 { int i=1,j,k,rsize,psize;
01160 eusinteger_t *rbv, *bbv, *pbv;
01161 pointer b,p,r=argv[0];
01162
01163 if (isbignum(r)) {
01164 r=copy_big(r); rsize=bigsize(r); rbv=bigvec(r);
01165 p=argv[i++];
01166 goto bigand;}
01167
01168 k=intval(r);
01169 while (i<n) {
01170 p=argv[i++];
01171 if (isint(p)) k &=intval(p);
01172 else if (isbignum(p)) {
01173 b=copy_big(p);
01174 p=makeint((eusinteger_t)r);
01175 r=b; rsize=bigsize(r); rbv=bigvec(r);
01176 goto bigand;}
01177 else error(E_NOINT);}
01178 return(makeint(k));
01179
01180 while (i<n) {
01181 p=argv[i++];
01182 bigand:
01183
01184 if (isint(p)) {
01185 rbv[0] &= intval(p);
01186 if (intval(p)>=0) for (j=1; j<rsize; j++) rbv[j]=0; }
01187 else if (isbignum(p)) {
01188 psize=bigsize(p);
01189 if (rsize>=psize) {
01190 for (j=0; j<psize; j++) rbv[j] &= p->c.bgnm.bv->c.ivec.iv[j];
01191 if (rsize>psize) {
01192 if (big_sign(p)>0) for (j=psize; j<rsize; j++) rbv[j]=0;}
01193 }
01194 else if (big_sign(r)<0) {
01195 r=extend_big(r,psize);
01196 rsize=psize; rbv=bigvec(r);
01197 for (j=0; j<psize; j++) rbv[j] &= p->c.bgnm.bv->c.ivec.iv[j];
01198 }
01199 else
01200 for (j=0; j<rsize; j++) rbv[j] &= p->c.bgnm.bv->c.ivec.iv[j];
01201 }
01202 else error(E_NOINT);}
01203 return(normalize_bignum(r));}
01204
01205 pointer LOGIOR(ctx,n,argv)
01206 register context *ctx;
01207 register int n;
01208 register pointer argv[];
01209 { register eusinteger_t result=0;
01210 register int i=0;
01211 pointer p;
01212 while (i<n) {
01213 p=argv[i];
01214 if (!isint(p)) {
01215 if (isbignum(p)) result |= bigintval(p);
01216 else error(E_NOINT);}
01217 else result |= intval(p);
01218 i++; }
01219 return(mkbigint(result));}
01220
01221 pointer LOGXOR(ctx,n,argv)
01222 register context *ctx;
01223 register int n;
01224 register pointer argv[];
01225 { register eusinteger_t result=0;
01226 register int i=0;
01227 while (i<n)
01228 if (!isint(argv[i])) error(E_NOINT);
01229 else result ^= intval(argv[i++]);
01230 return(makeint(result));}
01231
01232 pointer LOGEQV(ctx,n,argv)
01233 register context *ctx;
01234 register int n;
01235 register pointer argv[];
01236 { register eusinteger_t result=0;
01237 register int i=0;
01238 while (n>0) {
01239 if (!isint(argv[--n])) error(E_NOINT);
01240 result ^= intval(argv[n]); }
01241 return(makeint(~result));}
01242
01243 pointer LOGNAND(ctx,n,argv)
01244 register context *ctx;
01245 register int n;
01246 register pointer argv[];
01247 { register eusinteger_t result= ~0;
01248 register int i=0;
01249 while (i<n)
01250 if (!isint(argv[i])) error(E_NOINT);
01251 else result &= intval(argv[i++]);
01252 return(makeint(~result));}
01253
01254 pointer LOGNOR(ctx,n,argv)
01255 register context *ctx;
01256 register int n;
01257 register pointer argv[];
01258 { register eusinteger_t result=0;
01259 register int i=0;
01260 while (i<n)
01261 if (!isint(argv[i])) error(E_NOINT);
01262 else result |= intval(argv[i++]);
01263 return(makeint(~result));}
01264
01265 pointer LOGNOT(ctx,n,argv)
01266 register context *ctx;
01267 int n;
01268 pointer argv[];
01269 { eusinteger_t i;
01270 ckarg(1);
01271 if (!isint(argv[0])) error(E_NOINT);
01272 else {
01273 i=intval(argv[0]);
01274 return(makeint(~i));}}
01275
01276 pointer LOGTEST(ctx,n,argv)
01277 register context *ctx;
01278 int n;
01279 register pointer argv[];
01280 { ckarg(2);
01281 if (!isint(argv[0])) error(E_NOINT);
01282 if (!isint(argv[1])) error(E_NOINT);
01283 if ((eusinteger_t)argv[0] & (eusinteger_t)argv[1] & (eusinteger_t)~3) return(T);
01284 else return(NIL);}
01285
01286 pointer LOGBITP(ctx,n,argv)
01287 register context *ctx;
01288 register int n;
01289 register pointer argv[];
01290 { register eusinteger_t index,val;
01291 ckarg(2);
01292 index=ckintval(argv[0]);
01293 val=ckintval(argv[1]);
01294 if (index<0) error(E_NOINT);
01295 if ((val>>index) & 1) return(T); else return(NIL);}
01296
01297 pointer ASH(ctx,n,argv)
01298 register context *ctx;
01299 register int n;
01300 register pointer argv[];
01301 { register eusinteger_t count,val;
01302 register int firstone;
01303 register eusinteger_t sign;
01304 pointer a,b;
01305 ckarg(2);
01306 count=ckintval(argv[1]);
01307 if (isint(argv[0])) {
01308 val=intval(argv[0]);
01309 if (count<=0) return(makeint(val>>(-count)));
01310 if (val<=0) { return(makeint(val<<count));}
01311 #if (WORD_SIZE == 64)
01312 firstone=ffsl(val);
01313 #else
01314 firstone=ffs(val);
01315 #endif
01316 if ((firstone + count)<WORD_SIZE-2) {
01317 sign=(val>=0)?1:(-1);
01318 val=val<<count;
01319 if (sign>0) return(makeint(val));
01320 else return(makeint(~val)); }
01321
01322 a=makebig1(val);}
01323 else if (isbignum(argv[0])) { a=argv[0]; sign=big_sign(a);}
01324 else error(E_NOINT);
01325
01326
01327 { int size=bigsize(a);
01328 int i, j, k;
01329 eusinteger_t x, *av, *bv;
01330 pointer b=makebig(size+(count+(WORD_SIZE-1))/(WORD_SIZE-1));
01331 vpush(b);
01332 av=bigvec(a); bv=bigvec(b);
01333 if (count>=0) {
01334 j= count/(WORD_SIZE-1); k=count % (WORD_SIZE-1);
01335 for (i=0; i<size; i++) {
01336 x=av[i];
01337 bv[i+j] |= (x << k);
01338 bv[i+j+1] = (x>>((WORD_SIZE-1)-k)); } }
01339 else {
01340 count = -count;
01341 j=count/(WORD_SIZE-1); k=count % (WORD_SIZE-1);
01342 for (i=0; i<size-j-1; i++) {
01343 bv[i]=(av[j+i]>>k) | ((av[j+i+1]<<((WORD_SIZE-1)-k)) & MASK); }
01344 bv[size-j-1]=av[size-1]>>k;
01345 }
01346 b=normalize_bignum(b);
01347 vpop();
01348 return(b); }
01349 }
01350
01351 pointer LDB(ctx,n,argv)
01352 register context *ctx;
01353 register int n;
01354 register pointer argv[];
01355 { register eusinteger_t pos,width=8;
01356 #if (WORD_SIZE == 64)
01357 register unsigned long val;
01358 #else
01359 register unsigned int val;
01360 #endif
01361 ckarg2(2,3);
01362 val=ckintval(argv[0]); pos=ckintval(argv[1]);
01363 if (n==3) width=ckintval(argv[2]);
01364 val=(val<<(WORD_SIZE-pos-width))>>(WORD_SIZE-width);
01365 return(makeint(val));}
01366
01367 pointer DPB(ctx,n,argv)
01368 register context *ctx;
01369 int n;
01370 pointer argv[];
01371 { register eusinteger_t pos,width=8;
01372 #if (WORD_SIZE == 64)
01373 register unsigned long val,target,mask=~0L;
01374 #else
01375 register unsigned int val,target,mask=~0;
01376 #endif
01377 ckarg(4);
01378 val=ckintval(argv[0]);
01379 target=ckintval(argv[1]);
01380 pos=ckintval(argv[2]);
01381 width=ckintval(argv[3]);
01382 mask=mask<<(WORD_SIZE-(pos+width));
01383 mask=mask>>(WORD_SIZE-width);
01384 val &= mask;
01385 mask <<= pos;
01386 target=(target & ~mask) | (val<<pos);
01387 return(makeint(target));}
01388
01389 pointer MAKERANDOMSTATE(ctx,n,argv)
01390 register context *ctx;
01391 int n;
01392 register pointer argv[];
01393 { pointer state;
01394 pointer randvec;
01395 time_t tm;
01396
01397 ckarg2(0,1);
01398 state=NIL;
01399 randvec=makevector(C_INTVECTOR, 2);
01400 if (n==1) {
01401 state=argv[0];
01402 if (state==NIL) { goto MAKERANDSTATENIL; }
01403 else if (state==T) {
01404 if (time(&tm)==-1){
01405 error(E_USER,(pointer)"failed to fetch time"); }
01406 srand((unsigned int)tm);
01407 randvec->c.ivec.iv[0] = rand();
01408 randvec->c.ivec.iv[1] = rand();
01409 return (randvec); }
01410 if (!isintvector(state) && !isstring(state)) error(E_NOVECTOR);
01411 if (vecsize(state)<2) error(E_VECSIZE); }
01412 MAKERANDSTATENIL:
01413 if (state==NIL) {
01414 state=Spevalof(RANDSTATE);
01415 if (state==UNBOUND) state=speval(RANDSTATE); }
01416 randvec->c.ivec.iv[0] = state->c.ivec.iv[0];
01417 randvec->c.ivec.iv[1] = state->c.ivec.iv[1];
01418 return (randvec);
01419 }
01420
01421 pointer RANDOM(ctx,n,argv)
01422 register context *ctx;
01423 int n;
01424 register pointer argv[];
01425 { pointer a=argv[0],state;
01426 eusinteger_t imax,irandval;
01427 eusfloat_t fmax,frandval;
01428 double randval;
01429 double erand48();
01430 #if news || sanyo
01431 long random();
01432 #endif
01433 numunion nu;
01434
01435 ckarg2(1,2);
01436 if (n==2) {
01437 state=argv[1];
01438 if (!isintvector(state) && !isstring(state)) error(E_NOVECTOR);
01439 if (vecsize(state)<2) error(E_VECSIZE);}
01440 else {
01441 state=Spevalof(RANDSTATE);
01442 if (state==UNBOUND) state=speval(RANDSTATE);}
01443 #if news || sanyo
01444 randval=random();
01445 #else
01446 #if alpha
01447 randval=erand48((unsigned short *)state->c.ivec.iv);
01448 #elif Win32 || Cygwin
01449 randval=((double)rand())/RAND_MAX;
01450 #else
01451 randval=erand48((unsigned short *)(state->c.ivec.iv));
01452 #endif
01453 #endif
01454 if (isint(a)) {
01455 imax=intval(a);
01456 irandval=randval*imax;
01457 return(makeint(irandval));}
01458 else if (isflt(a)) {
01459 fmax=fltval(a);
01460 frandval=randval*fmax;
01461 return(makeflt(frandval));}
01462 else error(E_NONUMBER);
01463 }
01464
01465
01466 void arith(ctx,mod)
01467 register context *ctx;
01468 pointer mod;
01469 {
01470 defun(ctx,"=",mod,NUMEQUAL,NULL);
01471 defun(ctx,"/=",mod,NUMNEQUAL,NULL);
01472 defun(ctx,">",mod,GREATERP,NULL);
01473 defun(ctx,"<",mod,LESSP,NULL);
01474 defun(ctx,">=",mod,GREQP,NULL);
01475 defun(ctx,"<=",mod,LSEQP,NULL);
01476 defun(ctx,"MOD",mod,MOD,NULL);
01477 defun(ctx,"1-",mod,SUB1,NULL);
01478 defun(ctx,"1+",mod,ADD1,NULL);
01479 defun(ctx,"+",mod,PLUS,NULL);
01480 defun(ctx,"-",mod,MINUS,NULL);
01481 defun(ctx,"*",mod,TIMES,NULL);
01482 defun(ctx,"/",mod,QUOTIENT,NULL);
01483 defun(ctx,"SIN",mod,SIN,NULL);
01484 defun(ctx,"COS",mod,COS,NULL);
01485 defun(ctx,"TAN",mod,TAN,NULL);
01486 defun(ctx,"ATAN",mod,ATAN,NULL);
01487 defun(ctx,"TANH",mod,TANH,NULL);
01488 defun(ctx,"ATANH",mod,ATANH,NULL);
01489 defun(ctx,"SINH",mod,SINH,NULL);
01490 defun(ctx,"ASINH",mod,ASINH,NULL);
01491 defun(ctx,"COSH",mod,COSH,NULL);
01492 defun(ctx,"ACOSH",mod,ACOSH,NULL);
01493 defun(ctx,"SQRT",mod,SQRT,NULL);
01494 defun(ctx,"LOG",mod,LOG,NULL);
01495 defun(ctx,"EXP",mod,EXP,NULL);
01496 defun(ctx,"ABS",mod,ABS,NULL);
01497 defun(ctx,"ROUND",mod,ROUND,NULL);
01498 defun(ctx,"FLOOR",mod,FLOOR,NULL);
01499 defun(ctx,"CEILING",mod,CEILING,NULL);
01500 defun(ctx,"TRUNCATE",mod,TRUNCATE,NULL);
01501 defun(ctx,"FLOAT",mod,EUSFLOAT,NULL);
01502 defun(ctx,"DECODE-FLOAT",mod,DECFLOAT,NULL);
01503 defun(ctx,"MAX",mod,MAX,NULL);
01504 defun(ctx,"MIN",mod,MIN,NULL);
01505 defun(ctx,"LOGAND",mod,LOGAND,NULL);
01506 defun(ctx,"LOGIOR",mod,LOGIOR,NULL);
01507 defun(ctx,"LOGXOR",mod,LOGXOR,NULL);
01508 defun(ctx,"LOGEQV",mod,LOGEQV,NULL);
01509 defun(ctx,"LOGNAND",mod,LOGNAND,NULL);
01510 defun(ctx,"LOGNOR",mod,LOGNOR,NULL);
01511 defun(ctx,"LOGNOT",mod,LOGNOT,NULL);
01512 defun(ctx,"LOGTEST",mod,LOGTEST,NULL);
01513 defun(ctx,"LOGBITP",mod,LOGBITP,NULL);
01514 defun(ctx,"ASH",mod,ASH,NULL);
01515 defun(ctx,"LDB",mod,LDB,NULL);
01516 defun(ctx,"DPB",mod,DPB,NULL);
01517 defun(ctx,"MAKE-RANDOM-STATE",mod,MAKERANDOMSTATE,NULL);
01518 defun(ctx,"RANDOM",mod,RANDOM,NULL);
01519 defun(ctx,"FREXP",mod,FREXP,NULL);
01520 }