arith.c
Go to the documentation of this file.
00001 /****************************************************************/
00002 /* arith.c  EULISP arithmetic functions                 
00003 /* Copyright(c)1988 Toshihiro MATSUI, Electrotechnical Laboratory
00004 /*      1986-May
00005 .*      1988-Feb        boxing and unboxing recoded by macros
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); // #include <string.h> // ffsl
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 /* number predicates
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);} /* kanehiro's patch 2000.12.13 */
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)       /*less-or-equalp*/
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 /* extended numbers */
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))) { /* fixnum overflow */
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   /*  fprintf(stderr, "big plus\n"); */
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) {      /*negate*/
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)) {      /* buggy when numerator == MINNEGFIXNUM */
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   /* n>1 */
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))) { /* fixnum overflow */
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);  /* bignum -a is copied to z */
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; /*replace b on the stack*/
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 /*  fprintf(stderr, "TIMES ");
00703   for (i=0; i<n; i++) fprintf(stderr, "%x ", argv[i]);
00704   fprintf(stderr, "\n"); */
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) { /*overflow -->bignum */
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)) { /* fixnum times bignum */
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       /* Here, b is saved, (b * is) is going to be performed */
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:   /*quotient of ratios*/
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)    /*(decode-float FLOAT) -> int*/
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 /* bit wise logical operations
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     /* r is bignum */
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     /*extend to big*/
01322     a=makebig1(val);}
01323   else if (isbignum(argv[0])) { a=argv[0]; sign=big_sign(a);}
01324   else error(E_NOINT);
01325 
01326   /*shift b by count bits*/
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 {  /* count <0 ; shift right */
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) /*(LDB 'val 'pos 'width)*/
01352 register context *ctx;
01353 register int n;                 /*no byte specifier in euslisp*/
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 }


euslisp
Author(s): Toshihiro Matsui
autogenerated on Thu Jun 6 2019 18:05:53