home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / src / lisparit.d < prev    next >
Encoding:
Text File  |  1994-09-21  |  73.0 KB  |  2,063 lines

  1. # Arithmetik fⁿr CLISP
  2. # Bruno Haible 21.9.1994
  3.  
  4. #define LISPARIT      # im folgenden nicht nur die Macros, auch die Funktionen
  5.  
  6. #include "lispbibl.c"
  7.  
  8. #undef LF             # LF bedeutet hier nicht 'Linefeed', sondern 'LongFloat'
  9.  
  10.  
  11. # UP: entscheidet auf Zahlgleichheit
  12. # number_gleich(x,y)
  13. # > x,y: zwei Zahlen
  14. # < ergebnis: TRUE, falls (= x y) gilt
  15. # kann GC ausl÷sen
  16.   global boolean number_gleich (object x, object y);
  17.   #define N_N_gleich  number_gleich  # N_N_gleich wird spΣter definiert
  18.  
  19.  
  20. # zur Arithmetik allgemein:
  21. #include "aridecl.c"  # Deklarationen
  22. #include "arilev0.c"  # Maschinen-Arithmetik
  23. #include "arilev1.c"  # Digit-Sequences
  24. # zu Integers:
  25. #include "intelem.c"  # Elementaroperationen auf Integers
  26. #include "intlog.c"   # logische Operationen auf Integers
  27. #include "intplus.c"  # Addition, Subtraktion auf Integers
  28. #include "intcomp.c"  # Vergleichsoperationen auf Integers
  29. #include "intbyte.c"  # Byte-Operationen LDB, LOAD-BYTE, ...
  30. #include "intmal.c"   # Multiplikation von Integers
  31. #include "intdiv.c"   # Division von Integers
  32. #include "intgcd.c"   # ggT und kgV
  33. #include "int2adic.c" # Operationen mit 2-adischen Integers
  34. #include "intsqrt.c"  # Wurzel, ISQRT
  35. #include "intprint.c" # Hilfsfunktion zur Ausgabe von Integers
  36. #include "intread.c"  # Hilfsfunktion zur Eingabe von Integers
  37. # zu rationalen Zahlen:
  38. #include "rational.c" # Rationale Zahlen
  39. # zu Floats:
  40. #include "sfloat.c"   # Short-Float-Grundfunktionen
  41. #include "ffloat.c"   # Single-Float-Grundfunktionen
  42. #include "dfloat.c"   # Double-Float-Grundfunktionen
  43. #include "lfloat.c"   # Long-Float-Grundfunktionen
  44. #include "flo_konv.c" # Float-Konversionen
  45. #include "flo_rest.c" # Floats allgemein
  46. # zu reellen Zahlen:
  47. #include "realelem.c" # elementare Funktionen fⁿr reelle Zahlen
  48. #include "realrand.c" # Funktionen fⁿr Zufallszahlen
  49. #include "realtran.c" # transzendente Funktionen fⁿr reelle Zahlen
  50. # zu komplexen Zahlen:
  51. #include "compelem.c" # elementare Funktionen fⁿr komplexe Zahlen
  52. #include "comptran.c" # transzendente Funktionen fⁿr komplexe Zahlen
  53.  
  54.  
  55. # ============================================================================ #
  56. #                       Einleseroutinen fⁿr Zahlen
  57.  
  58. # UP: Multipliziert ein Integer mit 10 und addiert eine weitere Ziffer.
  59. # mal_10_plus_x(y,x)
  60. # > y: Integer Y (>=0)
  61. # > x: Ziffernwert X (>=0,<10)
  62. # < ergebnis: Integer Y*10+X (>=0)
  63. # kann GC ausl÷sen
  64.   global object mal_10_plus_x (object y, uintB x);
  65.   global object mal_10_plus_x(y,x)
  66.     var reg4 object y;
  67.     var reg6 uintB x;
  68.     { SAVE_NUM_STACK # num_stack retten
  69.       var reg1 uintD* MSDptr;
  70.       var reg2 uintC len;
  71.       var reg5 uintD* LSDptr;
  72.       I_to_NDS_1(y, MSDptr=,len=,LSDptr=); # NDS zu Y
  73.      {var reg3 uintD carry = mulusmall_loop_down(10,LSDptr,len,x); # mal 10, plus x
  74.       if (!(carry==0))
  75.         { *--MSDptr = carry; len++;
  76.           if (uintCoverflow(len)) { BN_ueberlauf(); } # ▄berlauf der LΣnge?
  77.         }
  78.       RESTORE_NUM_STACK # num_stack (vorzeitig) zurⁿck
  79.       return UDS_to_I(MSDptr,len); # UDS als Integer zurⁿck
  80.     }}
  81.  
  82. # UP: Wandelt eine Zeichenkette mit Integer-Syntax in ein Integer um.
  83. # Punkte werden ⁿberlesen.
  84. # read_integer(base,sign,string,index1,index2)
  85. # > base: Lesebasis (>=2, <=36)
  86. # > sign: Vorzeichen (/=0 falls negativ)
  87. # > string: Simple-String (enthΣlt Ziffern mit Wert <base und evtl. Punkt)
  88. # > index1: Index der ersten Ziffer
  89. # > index2: Index nach der letzten Ziffer
  90. #   (also index2-index1 Ziffern, incl. evtl. Dezimalpunkt am Schlu▀)
  91. # < ergebnis: Integer
  92. # kann GC ausl÷sen
  93.   global object read_integer (uintWL base,
  94.          signean sign, object string, uintL index1, uintL index2);
  95.   global object read_integer(base,sign,string,index1,index2)
  96.     var reg6 uintWL base;
  97.     var reg5 signean sign;
  98.     var reg3 object string;
  99.     var reg1 uintL index1;
  100.     var reg4 uintL index2;
  101.     { var reg2 object x = # in Integer umwandeln:
  102.         DIGITS_to_I(&TheSstring(string)->data[index1],index2-index1,(uintD)base);
  103.       if (sign==0)
  104.         { return x; }
  105.         else
  106.         { return I_minus_I(x); } # negatives Vorzeichen -> Vorzeichenwechsel
  107.     }
  108.  
  109. # UP: Wandelt eine Zeichenkette mit Rational-Syntax in eine rationale Zahl um.
  110. # read_rational(base,sign,string,index1,index3,index2)
  111. # > base: Lesebasis (>=2, <=36)
  112. # > sign: Vorzeichen (/=0 falls negativ)
  113. # > string: Simple-String (enthΣlt Ziffern mit Wert <base und Bruchstrich)
  114. # > index1: Index der ersten Ziffer
  115. # > index3: Index von '/'
  116. # > index2: Index nach der letzten Ziffer
  117. #   (also index3-index1 ZΣhler-Ziffern, index2-index3-1 Nenner-Ziffern)
  118. # < ergebnis: rationale Zahl
  119. # kann GC ausl÷sen
  120.   global object read_rational (uintWL base,
  121.          signean sign, object string, uintL index1, uintL index3, uintL index2);
  122.   global object read_rational(base,sign,string,index1,index3,index2)
  123.     var reg7 uintWL base;
  124.     var reg8 signean sign;
  125.     var reg2 object string;
  126.     var reg5 uintL index1;
  127.     var reg3 uintL index3;
  128.     var reg6 uintL index2;
  129.     { pushSTACK(string); # string retten
  130.      {var reg4 uintL index3_1 = index3+1; # Index der ersten Nennerziffer
  131.       var reg1 object x = # Nenner
  132.         DIGITS_to_I(&TheSstring(string)->data[index3_1],index2-index3_1,(uintD)base);
  133.       if (eq(x,Fixnum_0)) { divide_0(); } # Division durch 0 abfangen
  134.       string = STACK_0; STACK_0 = x;
  135.      }
  136.      {var reg1 object x = # ZΣhler
  137.         DIGITS_to_I(&TheSstring(string)->data[index1],index3-index1,(uintD)base);
  138.       if (!(sign==0)) { x = I_minus_I(x); } # incl. Vorzeichen
  139.       return I_posI_durch_RA(x,popSTACK()); # ZΣhler/Nenner als Bruch
  140.     }}
  141.  
  142. # UP: Wandelt eine Zeichenkette mit Float-Syntax in ein Float um.
  143. # read_float(base,sign,string,index1,index4,index2,index3)
  144. # > base: Lesebasis (=10)
  145. # > sign: Vorzeichen (/=0 falls negativ)
  146. # > string: Simple-String (enthΣlt Ziffern und evtl. Punkt und Exponentmarker)
  147. # > index1: Index vom Mantissenanfang (excl. Vorzeichen)
  148. # > index4: Index nach dem Mantissenende
  149. # > index2: Index beim Ende der Characters
  150. # > index3: Index nach dem Dezimalpunkt (=index4 falls keiner da)
  151. #   (also Mantisse mit index4-index1 Characters: Ziffern und max. 1 '.')
  152. #   (also index4-index3 Nachkommaziffern)
  153. #   (also bei index4<index2: index4 = Index des Exponent-Markers,
  154. #    index4+1 = Index des Exponenten-Vorzeichens oder der ersten
  155. #    Exponenten-Ziffer)
  156. # < ergebnis: Float
  157. # kann GC ausl÷sen
  158.   global object read_float (uintWL base,
  159.          signean sign, object string, uintL index1, uintL index4, uintL index2, uintL index3);
  160.   global object read_float(base,sign,string,index1,index4,index2,index3)
  161.     var reg7 uintWL base;
  162.     var reg10 signean sign;
  163.     var reg5 object string;
  164.     var reg9 uintL index1;
  165.     var reg8 uintL index4;
  166.     var reg9 uintL index2;
  167.     var reg9 uintL index3;
  168.     { pushSTACK(string); # string retten
  169.       # Exponent:
  170.      {var reg3 uintB exp_marker;
  171.       var reg2 object exponent;
  172.       {var reg6 uintL exp_len = index2-index4; # Anzahl Stellen des Exponenten
  173.        if (exp_len > 0)
  174.          { var reg1 uintB* ptr = &TheSstring(string)->data[index4]; # zeigt auf den Exponentmarker
  175.            exp_marker = *ptr++; exp_len--; # Exponentmarker ⁿberlesen
  176.                         # (als Gro▀buchstabe, da vom Aufrufer umgewandelt)
  177.           {var reg4 signean exp_sign = 0; # Exponenten-Vorzeichen
  178.            switch (*ptr)
  179.              { case '-': exp_sign = ~exp_sign; # Vorzeichen := negativ
  180.                case '+': ptr++; exp_len--; # Exponenten-Vorzeichen ⁿberlesen
  181.                default: ;
  182.              }
  183.            exponent = DIGITS_to_I(ptr,exp_len,(uintD)base); # Exponent in Integer umwandeln
  184.            if (!(exp_sign==0)) { exponent = I_minus_I(exponent); } # incl. Vorzeichen
  185.          }}
  186.          else
  187.          # kein Exponent da
  188.          { exp_marker = 'E'; exponent = Fixnum_0; }
  189.        # exp_marker = Exponentmarker als Gro▀buchtabe,
  190.        # exponent = Exponent als Integer.
  191.        exponent = # Exponent - Anzahl der Nachkommaziffern
  192.          I_I_minus_I(exponent,fixnum(index4-index3));
  193.        exponent = # 10^exponent = zu multiplizierende Zehnerpotenz
  194.          R_I_expt_R(fixnum(base),exponent);
  195.        string = STACK_0; STACK_0 = exponent;
  196.        # Mantisse:
  197.        {var reg1 object mantisse = # Mantisse als Integer
  198.          DIGITS_to_I(&TheSstring(string)->data[index1],index4-index1,(uintD)base);
  199.         exponent = popSTACK();
  200.         # Mantisse (Integer) und Exponent (rational >0) unelegant zusammenmultiplizieren:
  201.         if (RA_integerp(exponent))
  202.           { mantisse = I_I_mal_I(mantisse,exponent); }
  203.           else
  204.           { # falls mantisse/=0, in exponent=1/10^i den ZΣhler durch mantisse
  205.             # ersetzen (liefert ungekⁿrzten Bruch, Vorsicht!)
  206.             if (!(eq(mantisse,Fixnum_0)))
  207.               { TheRatio(exponent)->rt_num = mantisse; mantisse = exponent; }
  208.           }
  209.         # mantisse = Mantisse * Zehnerpotenz, als ungekⁿrzte rationale Zahl!
  210.         switch (exp_marker)
  211.           { case 'S': SF: # in Short-Float umwandeln
  212.               {var reg4 object x = RA_to_SF(mantisse);
  213.                return (sign==0 ? x : SF_minus_SF(x)); # evtl. noch Vorzeichenwechsel
  214.               }
  215.             case 'F': FF: # in Single-Float umwandeln
  216.               {var reg4 object x = RA_to_FF(mantisse);
  217.                return (sign==0 ? x : FF_minus_FF(x)); # evtl. noch Vorzeichenwechsel
  218.               }
  219.             case 'D': DF: # in Double-Float umwandeln
  220.               {var reg4 object x = RA_to_DF(mantisse);
  221.                return (sign==0 ? x : DF_minus_DF(x)); # evtl. noch Vorzeichenwechsel
  222.               }
  223.             case 'L': LF: # in Long-Float der Default-Genauigkeit umwandeln
  224.               {var reg4 object x = RA_to_LF(mantisse,I_to_UL(O(LF_digits)));
  225.                return (sign==0 ? x : LF_minus_LF(x)); # evtl. noch Vorzeichenwechsel
  226.               }
  227.             default: # case 'E':
  228.               defaultfloatcase(S(read_default_float_format),
  229.                                goto SF; , goto FF; , goto DF; , goto LF; ,
  230.                                pushSTACK(mantisse); , mantisse = popSTACK();
  231.                               );
  232.           }
  233.     }}}}
  234.  
  235.  
  236. # ============================================================================ #
  237. #                       Ausgaberoutinen fⁿr Zahlen
  238.  
  239. # UP: Gibt ein Integer aus.
  240. # print_integer(z,base,&stream);
  241. # > z: Integer
  242. # > base: Basis (>=2, <=36)
  243. # > stream: Stream
  244. # < stream: Stream
  245. # kann GC ausl÷sen
  246.   global void print_integer (object z, uintWL base, object* stream_);
  247.   global void print_integer(z,base,stream_)
  248.     var reg6 object z;
  249.     var reg8 uintWL base;
  250.     var reg3 object* stream_;
  251.     { if (R_minusp(z))
  252.         # z<0 -> Vorzeichen ausgeben:
  253.         { pushSTACK(z);
  254.           write_schar(stream_,'-');
  255.           z = I_minus_I(popSTACK());
  256.         }
  257.      { SAVE_NUM_STACK # num_stack retten
  258.        var reg5 uintD* MSDptr;
  259.        var reg4 uintC len;
  260.        I_to_NDS(z, MSDptr=,len=,); # z als UDS
  261.       {var reg7 uintL need = digits_need(len,base);
  262.        var DYNAMIC_ARRAY(reg9,ziffern,uintB,need); # Platz fⁿr die Ziffern
  263.        var DIGITS erg; erg.LSBptr = &ziffern[need];
  264.        UDS_to_DIGITS(MSDptr,len,(uintD)base,&erg); # Umwandlung in Ziffern
  265.        # Ziffern ausgeben:
  266.        {var reg1 uintB* ptr = erg.MSBptr;
  267.         var reg2 uintL count;
  268.         dotimespL(count,erg.len, { write_schar(stream_,*ptr++); } );
  269.        }
  270.        FREE_DYNAMIC_ARRAY(ziffern);
  271.        RESTORE_NUM_STACK # num_stack zurⁿck
  272.     }}}
  273.  
  274. # UP: Gibt ein Float aus.
  275. # print_float(z,&stream);
  276. # > z: Float
  277. # > stream: Stream
  278. # < stream: Stream
  279. # kann GC ausl÷sen
  280.   global void print_float (object z, object* stream_);
  281.   global void print_float(z,stream_)
  282.     var reg4 object z;
  283.     var reg1 object* stream_;
  284.     { # Falls SYS::WRITE-FLOAT definiert ist, (SYS::WRITE-FLOAT stream z) aufrufen:
  285.       var reg3 object fun = Symbol_function(S(write_float));
  286.       if (!eq(fun,unbound))
  287.         # Funktion aufrufen
  288.         { pushSTACK(*stream_); pushSTACK(z); funcall(fun,2); }
  289.         else
  290.         # eigene Routine: gibt
  291.         # Vorzeichen, Punkt, Mantisse (binΣr), (Zweiersystem-)Exponent (dezimal)
  292.         # aus.
  293.         { pushSTACK(z);
  294.           F_integer_decode_float_I_I_I(z);
  295.           # Stackaufbau: z, m, e, s.
  296.           # Vorzeichen ausgeben, falls <0:
  297.           if (eq(STACK_0,Fixnum_minus1)) { write_schar(stream_,'-'); }
  298.           # Mantisse binΣr(!) ausgeben:
  299.           write_schar(stream_,'.');
  300.           print_integer(STACK_2,2,stream_);
  301.           # Exponent-Marker ausgeben:
  302.           {var reg2 object exp_marker;
  303.            floatcase(STACK_3,
  304.                      { exp_marker = code_char('s'); },
  305.                      { exp_marker = code_char('f'); },
  306.                      { exp_marker = code_char('d'); },
  307.                      { exp_marker = code_char('L'); }
  308.                     );
  309.            write_char(stream_,exp_marker);
  310.           }
  311.           # Exponenten dezimal ausgeben:
  312.           print_integer(L_to_I(F_exponent_L(STACK_3)),10,stream_);
  313.           skipSTACK(4);
  314.         }
  315.     }
  316.  
  317.  
  318. # ============================================================================ #
  319. #                           Lisp-Funktionen
  320.  
  321. # Fehlermeldung, wenn keine Zahl kommt.
  322. # > obj: Objekt, keine Zahl
  323. # > subr_self: Aufrufer (ein SUBR)
  324.   nonreturning_function(local, fehler_not_N, (object obj));
  325.   local void fehler_not_N(obj)
  326.     var reg1 object obj;
  327.     { pushSTACK(obj); # Wert fⁿr Slot DATUM von TYPE-ERROR
  328.       pushSTACK(S(number)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  329.       pushSTACK(obj);
  330.       pushSTACK(TheSubr(subr_self)->name);
  331.       fehler(type_error,
  332.              DEUTSCH ? "Argument zu ~ mu▀ eine Zahl sein: ~" :
  333.              ENGLISH ? "argument to ~ should be a number: ~" :
  334.              FRANCAIS ? "L'argument pour ~ doit Ωtre un nombre et non ~." :
  335.              ""
  336.             );
  337.     }
  338.  
  339. # Fehlermeldung, wenn keine reelle Zahl kommt.
  340. # > obj: Objekt, keine reelle Zahl
  341. # > subr_self: Aufrufer (ein SUBR)
  342.   nonreturning_function(local, fehler_not_R, (object obj));
  343.   local void fehler_not_R(obj)
  344.     var reg1 object obj;
  345.     { pushSTACK(obj); # Wert fⁿr Slot DATUM von TYPE-ERROR
  346.       pushSTACK(S(real)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  347.       pushSTACK(obj);
  348.       pushSTACK(TheSubr(subr_self)->name);
  349.       fehler(type_error,
  350.              DEUTSCH ? "Argument zu ~ mu▀ eine reelle Zahl sein: ~" :
  351.              ENGLISH ? "argument to ~ should be a real number: ~" :
  352.              FRANCAIS ? "L'argument pour ~ doit Ωtre un nombre rΘel et non ~." :
  353.              ""
  354.             );
  355.     }
  356.  
  357. # Fehlermeldung, wenn keine Floating-Point-Zahl kommt.
  358. # > obj: Objekt, keine Floating-Point-Zahl
  359. # > subr_self: Aufrufer (ein SUBR)
  360.   nonreturning_function(local, fehler_not_F, (object obj));
  361.   local void fehler_not_F(obj)
  362.     var reg1 object obj;
  363.     { pushSTACK(obj); # Wert fⁿr Slot DATUM von TYPE-ERROR
  364.       pushSTACK(S(float)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  365.       pushSTACK(obj);
  366.       pushSTACK(TheSubr(subr_self)->name);
  367.       fehler(type_error,
  368.              DEUTSCH ? "Argument zu ~ mu▀ eine Floating-Point-Zahl sein: ~" :
  369.              ENGLISH ? "argument to ~ should be a floating point number: ~" :
  370.              FRANCAIS ? "L'argument pour ~ doit Ωtre un nombre α virgule flottante et non ~." :
  371.              ""
  372.             );
  373.     }
  374.  
  375. # Fehlermeldung, wenn keine rationale Zahl kommt.
  376. # > obj: Objekt, keine rationale Zahl
  377. # > subr_self: Aufrufer (ein SUBR)
  378.   nonreturning_function(local, fehler_not_RA, (object obj));
  379.   local void fehler_not_RA(obj)
  380.     var reg1 object obj;
  381.     { pushSTACK(obj); # Wert fⁿr Slot DATUM von TYPE-ERROR
  382.       pushSTACK(S(rational)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  383.       pushSTACK(obj);
  384.       pushSTACK(TheSubr(subr_self)->name);
  385.       fehler(type_error,
  386.              DEUTSCH ? "Argument zu ~ mu▀ eine rationale Zahl sein: ~" :
  387.              ENGLISH ? "argument to ~ should be a rational number: ~" :
  388.              FRANCAIS ? "L'argument pour ~ doit Ωtre un nombre rationnel et non ~." :
  389.              ""
  390.             );
  391.     }
  392.  
  393. # Fehlermeldung, wenn keine ganze Zahl kommt.
  394. # > obj: Objekt, keine ganze Zahl
  395. # > subr_self: Aufrufer (ein SUBR)
  396.   nonreturning_function(local, fehler_not_I, (object obj));
  397.   local void fehler_not_I(obj)
  398.     var reg1 object obj;
  399.     { pushSTACK(obj); # Wert fⁿr Slot DATUM von TYPE-ERROR
  400.       pushSTACK(S(integer)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  401.       pushSTACK(obj);
  402.       pushSTACK(TheSubr(subr_self)->name);
  403.       fehler(type_error,
  404.              DEUTSCH ? "Argument zu ~ mu▀ eine ganze Zahl sein: ~" :
  405.              ENGLISH ? "argument to ~ should be an integer: ~" :
  406.              FRANCAIS ? "L'argument pour ~ doit Ωtre un nombre entier et non ~." :
  407.              ""
  408.             );
  409.     }
  410.  
  411. # Fehlermeldung wegen illegalem Digits-Argument obj.
  412. # > obj: Objekt
  413. # > subr_self: Aufrufer (ein SUBR)
  414.   nonreturning_function(local, fehler_digits, (object obj));
  415.   local void fehler_digits(obj)
  416.     var reg1 object obj;
  417.     { pushSTACK(obj); # Wert fⁿr Slot DATUM von TYPE-ERROR
  418.       pushSTACK(O(type_posfixnum1)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  419.       pushSTACK(obj);
  420.       pushSTACK(TheSubr(subr_self)->name);
  421.       fehler(type_error,
  422.              DEUTSCH ? "~: Argument mu▀ ein Fixnum >0 sein, nicht ~" :
  423.              ENGLISH ? "~: argument should be a positive fixnum, not ~" :
  424.              FRANCAIS ? "~ : L'argument doit Ωtre de type FIXNUM positif et non ~." :
  425.              ""
  426.             );
  427.     }
  428.  
  429. # check_number(obj) ⁿberprⁿft, ob obj eine Zahl ist.
  430. # > subr_self: Aufrufer (ein SUBR)
  431.   #define check_number(obj)  { if (!numberp(obj)) { fehler_not_N(obj); } }
  432.  
  433. # check_real(obj) ⁿberprⁿft, ob obj eine reelle Zahl ist.
  434. # > subr_self: Aufrufer (ein SUBR)
  435.   #define check_real(obj)  if_realp(obj, ; , { fehler_not_R(obj); } );
  436.  
  437. # check_float(obj) ⁿberprⁿft, ob obj eine Floating-Point-Zahl ist.
  438. # > subr_self: Aufrufer (ein SUBR)
  439.   #define check_float(obj)  { if (!floatp(obj)) { fehler_not_F(obj); } }
  440.  
  441. # check_rational(obj) ⁿberprⁿft, ob obj eine rationale Zahl ist.
  442. # > subr_self: Aufrufer (ein SUBR)
  443.   #define check_rational(obj)  if_rationalp(obj, ; , { fehler_not_RA(obj); } );
  444.  
  445. # check_integer(obj) ⁿberprⁿft, ob obj eine ganze Zahl ist.
  446. # > subr_self: Aufrufer (ein SUBR)
  447.   #define check_integer(obj)  { if (!integerp(obj)) { fehler_not_I(obj); } }
  448.  
  449. LISPFUNN(decimal_string,1)
  450. # (SYS::DECIMAL-STRING integer)
  451. # liefert zu einem Integer >=0  (write-to-string integer :base 10 :radix nil),
  452. # also die Ziffernfolge als Simple-String.
  453.   { var reg1 object x = popSTACK();
  454.     check_integer(x);
  455.     { SAVE_NUM_STACK # num_stack retten
  456.       var reg3 uintD* MSDptr;
  457.       var reg2 uintC len;
  458.       I_to_NDS(x, MSDptr=,len=,); # x (>=0) als UDS
  459.      {var reg4 uintL need = digits_need(len,10);
  460.       var DYNAMIC_ARRAY(reg5,ziffern,uintB,need); # Platz fⁿr die Ziffern
  461.       var DIGITS erg; erg.LSBptr = &ziffern[need];
  462.       UDS_to_DIGITS(MSDptr,len,10,&erg); # Umwandlung in Ziffern
  463.       RESTORE_NUM_STACK # num_stack (vorzeitig) zurⁿck
  464.       value1 = make_string(erg.MSBptr,erg.len); # Ziffern in Simple-String schreiben
  465.       mv_count=1;
  466.       FREE_DYNAMIC_ARRAY(ziffern);
  467.   } }}
  468.  
  469. LISPFUNN(zerop,1)
  470. # (ZEROP number), CLTL S. 195
  471.   { var reg1 object x = popSTACK();
  472.     check_number(x);
  473.     value1 = (N_zerop(x) ? T : NIL); mv_count=1;
  474.   }
  475.  
  476. LISPFUNN(plusp,1)
  477. # (PLUSP real), CLTL S. 196
  478.   { var reg1 object x = popSTACK();
  479.     check_real(x);
  480.     value1 = (R_plusp(x) ? T : NIL); mv_count=1;
  481.   }
  482.  
  483. LISPFUNN(minusp,1)
  484. # (MINUSP real), CLTL S. 196
  485.   { var reg1 object x = popSTACK();
  486.     check_real(x);
  487.     value1 = (R_minusp(x) ? T : NIL); mv_count=1;
  488.   }
  489.  
  490. LISPFUNN(oddp,1)
  491. # (ODDP integer), CLTL S. 196
  492.   { var reg1 object x = popSTACK();
  493.     check_integer(x);
  494.     value1 = (I_oddp(x) ? T : NIL); mv_count=1;
  495.   }
  496.  
  497. LISPFUNN(evenp,1)
  498. # (EVENP integer), CLTL S. 196
  499.   { var reg1 object x = popSTACK();
  500.     check_integer(x);
  501.     value1 = (I_oddp(x) ? NIL : T); mv_count=1;
  502.   }
  503.  
  504. # UP: Testet, ob alle argcount+1 Argumente unterhalb von args_pointer
  505. # Zahlen sind. Wenn nein, Error.
  506. # > argcount: Argumentezahl-1
  507. # > args_pointer: Pointer ⁿber die Argumente
  508. # > subr_self: Aufrufer (ein SUBR)
  509.   local void test_number_args (uintC argcount, object* args_pointer);
  510.   local void test_number_args(argcount,args_pointer)
  511.     var reg2 uintC argcount;
  512.     var reg1 object* args_pointer;
  513.     { dotimespC(argcount,argcount+1,
  514.         { var reg3 object arg = NEXT(args_pointer); # nΣchstes Argument
  515.           check_number(arg); # mu▀ eine Zahl sein
  516.         });
  517.     }
  518.  
  519. # UP: Testet, ob alle argcount+1 Argumente unterhalb von args_pointer
  520. # reelle Zahlen sind. Wenn nein, Error.
  521. # > argcount: Argumentezahl-1
  522. # > args_pointer: Pointer ⁿber die Argumente
  523. # > subr_self: Aufrufer (ein SUBR)
  524.   local void test_real_args (uintC argcount, object* args_pointer);
  525.   local void test_real_args(argcount,args_pointer)
  526.     var reg2 uintC argcount;
  527.     var reg1 object* args_pointer;
  528.     { dotimespC(argcount,argcount+1,
  529.         { var reg3 object arg = NEXT(args_pointer); # nΣchstes Argument
  530.           check_real(arg); # mu▀ eine reelle Zahl sein
  531.         });
  532.     }
  533.  
  534. # UP: Testet, ob alle argcount+1 Argumente unterhalb von args_pointer
  535. # ganze Zahlen sind. Wenn nein, Error.
  536. # > argcount: Argumentezahl-1
  537. # > args_pointer: Pointer ⁿber die Argumente
  538. # > subr_self: Aufrufer (ein SUBR)
  539.   local void test_integer_args (uintC argcount, object* args_pointer);
  540.   local void test_integer_args(argcount,args_pointer)
  541.     var reg2 uintC argcount;
  542.     var reg1 object* args_pointer;
  543.     { dotimespC(argcount,argcount+1,
  544.         { var reg3 object arg = NEXT(args_pointer); # nΣchstes Argument
  545.           check_integer(arg); # mu▀ eine ganze Zahl sein
  546.         });
  547.     }
  548.  
  549. LISPFUN(gleich,1,0,rest,nokey,0,NIL)
  550. # (= number {number}), CLTL S. 196
  551.   { var reg4 object* args_pointer = rest_args_pointer STACKop 1;
  552.     test_number_args(argcount,args_pointer); # Alle Argumente Zahlen?
  553.     # Methode:
  554.     # n+1 Argumente Arg[0..n].
  555.     # for i:=0 to n-1 do ( if Arg[i]/=Arg[i+1] then return(NIL) ), return(T).
  556.     { var reg1 object* arg_i_ptr = args_pointer;
  557.       dotimesC(argcount,argcount,
  558.         { var reg3 object arg_i = NEXT(arg_i_ptr);
  559.           if (!N_N_gleich(arg_i,Next(arg_i_ptr))) goto no;
  560.         });
  561.     }
  562.     yes: value1 = T; goto ok;
  563.     no: value1 = NIL; goto ok;
  564.     ok: mv_count=1; set_args_end_pointer(args_pointer);
  565.   }
  566.  
  567. LISPFUN(ungleich,1,0,rest,nokey,0,NIL)
  568. # (/= number {number}), CLTL S. 196
  569.   { var reg4 object* args_pointer = rest_args_pointer STACKop 1;
  570.     test_number_args(argcount,args_pointer); # Alle Argumente Zahlen?
  571.     # Methode:
  572.     # n+1 Argumente Arg[0..n].
  573.     # for j:=1 to n do
  574.     #   for i:=0 to j-1 do
  575.     #     if Arg[i]=Arg[j] then return(NIL),
  576.     # return(T).
  577.     { var reg2 object* arg_j_ptr = rest_args_pointer;
  578.       dotimesC(argcount,argcount,
  579.         { var reg1 object* arg_i_ptr = args_pointer;
  580.           do { if (N_N_gleich(NEXT(arg_i_ptr),Next(arg_j_ptr))) goto no; }
  581.              until (arg_i_ptr==arg_j_ptr);
  582.         });
  583.     }
  584.     yes: value1 = T; goto ok;
  585.     no: value1 = NIL; goto ok;
  586.     ok: mv_count=1; set_args_end_pointer(args_pointer);
  587.   }
  588.  
  589. LISPFUN(kleiner,1,0,rest,nokey,0,NIL)
  590. # (< real {real}), CLTL S. 196
  591.   { var reg4 object* args_pointer = rest_args_pointer STACKop 1;
  592.     test_real_args(argcount,args_pointer); # Alle Argumente reelle Zahlen?
  593.     # Methode:
  594.     # n+1 Argumente Arg[0..n].
  595.     # for i:=0 to n-1 do ( if Arg[i]>=Arg[i+1] then return(NIL) ), return(T).
  596.     { var reg1 object* arg_i_ptr = args_pointer;
  597.       dotimesC(argcount,argcount,
  598.         { var reg3 object arg_i = NEXT(arg_i_ptr);
  599.           if (R_R_comp(arg_i,Next(arg_i_ptr))>=0) goto no;
  600.         });
  601.     }
  602.     yes: value1 = T; goto ok;
  603.     no: value1 = NIL; goto ok;
  604.     ok: mv_count=1; set_args_end_pointer(args_pointer);
  605.   }
  606.  
  607. LISPFUN(groesser,1,0,rest,nokey,0,NIL)
  608. # (> real {real}), CLTL S. 196
  609.   { var reg4 object* args_pointer = rest_args_pointer STACKop 1;
  610.     test_real_args(argcount,args_pointer); # Alle Argumente reelle Zahlen?
  611.     # Methode:
  612.     # n+1 Argumente Arg[0..n].
  613.     # for i:=0 to n-1 do ( if Arg[i]<=Arg[i+1] then return(NIL) ), return(T).
  614.     { var reg1 object* arg_i_ptr = args_pointer;
  615.       dotimesC(argcount,argcount,
  616.         { var reg3 object arg_i = NEXT(arg_i_ptr);
  617.           if (R_R_comp(arg_i,Next(arg_i_ptr))<=0) goto no;
  618.         });
  619.     }
  620.     yes: value1 = T; goto ok;
  621.     no: value1 = NIL; goto ok;
  622.     ok: mv_count=1; set_args_end_pointer(args_pointer);
  623.   }
  624.  
  625. LISPFUN(klgleich,1,0,rest,nokey,0,NIL)
  626. # (<= real {real}), CLTL S. 196
  627.   { var reg4 object* args_pointer = rest_args_pointer STACKop 1;
  628.     test_real_args(argcount,args_pointer); # Alle Argumente reelle Zahlen?
  629.     # Methode:
  630.     # n+1 Argumente Arg[0..n].
  631.     # for i:=0 to n-1 do ( if Arg[i]>Arg[i+1] then return(NIL) ), return(T).
  632.     { var reg1 object* arg_i_ptr = args_pointer;
  633.       dotimesC(argcount,argcount,
  634.         { var reg3 object arg_i = NEXT(arg_i_ptr);
  635.           if (R_R_comp(arg_i,Next(arg_i_ptr))>0) goto no;
  636.         });
  637.     }
  638.     yes: value1 = T; goto ok;
  639.     no: value1 = NIL; goto ok;
  640.     ok: mv_count=1; set_args_end_pointer(args_pointer);
  641.   }
  642.  
  643. LISPFUN(grgleich,1,0,rest,nokey,0,NIL)
  644. # (>= real {real}), CLTL S. 196
  645.   { var reg4 object* args_pointer = rest_args_pointer STACKop 1;
  646.     test_real_args(argcount,args_pointer); # Alle Argumente reelle Zahlen?
  647.     # Methode:
  648.     # n+1 Argumente Arg[0..n].
  649.     # for i:=0 to n-1 do ( if Arg[i]<Arg[i+1] then return(NIL) ), return(T).
  650.     { var reg1 object* arg_i_ptr = args_pointer;
  651.       dotimesC(argcount,argcount,
  652.         { var reg3 object arg_i = NEXT(arg_i_ptr);
  653.           if (R_R_comp(arg_i,Next(arg_i_ptr))<0) goto no;
  654.         });
  655.     }
  656.     yes: value1 = T; goto ok;
  657.     no: value1 = NIL; goto ok;
  658.     ok: mv_count=1; set_args_end_pointer(args_pointer);
  659.   }
  660.  
  661. LISPFUN(max,1,0,rest,nokey,0,NIL)
  662. # (MAX real {real}), CLTL S. 198
  663. # Methode:
  664. # (max x1 x2 x3 ... xn) = (max ...(max (max x1 x2) x3)... xn)
  665.   { var reg4 object* args_pointer = rest_args_pointer STACKop 1;
  666.     test_real_args(argcount,args_pointer); # Alle Argumente reelle Zahlen?
  667.     # Methode:
  668.     # n+1 Argumente Arg[0..n].
  669.     # x:=Arg[0], for i:=1 to n do ( x := max(x,Arg[i]) ), return(x).
  670.     { var reg1 object* arg_i_ptr = args_pointer;
  671.       var reg2 object x = NEXT(arg_i_ptr); # bisheriges Maximum
  672.       dotimesC(argcount,argcount, { x = R_R_max_R(x,NEXT(arg_i_ptr)); } );
  673.       value1 = x; mv_count=1; set_args_end_pointer(args_pointer);
  674.   } }
  675.  
  676. LISPFUN(min,1,0,rest,nokey,0,NIL)
  677. # (MIN real {real}), CLTL S. 198
  678. # Methode:
  679. # (min x1 x2 x3 ... xn) = (min ...(min (min x1 x2) x3)... xn)
  680.   { var reg4 object* args_pointer = rest_args_pointer STACKop 1;
  681.     test_real_args(argcount,args_pointer); # Alle Argumente reelle Zahlen?
  682.     # Methode:
  683.     # n+1 Argumente Arg[0..n].
  684.     # x:=Arg[0], for i:=1 to n do ( x := min(x,Arg[i]) ), return(x).
  685.     { var reg1 object* arg_i_ptr = args_pointer;
  686.       var reg2 object x = NEXT(arg_i_ptr); # bisheriges Minimum
  687.       dotimesC(argcount,argcount, { x = R_R_min_R(x,NEXT(arg_i_ptr)); } );
  688.       value1 = x; mv_count=1; set_args_end_pointer(args_pointer);
  689.   } }
  690.  
  691. LISPFUN(plus,0,0,rest,nokey,0,NIL)
  692. # (+ {number}), CLTL S. 199
  693. # Methode:
  694. # (+) = 0
  695. # (+ x1 x2 x3 ... xn) = (+ ...(+ (+ x1 x2) x3)... xn)
  696.   { if (argcount==0) { value1 = Fixnum_0; mv_count=1; return; }
  697.     argcount--;
  698.     test_number_args(argcount,rest_args_pointer); # Alle Argumente Zahlen?
  699.     # Methode:
  700.     # n+1 Argumente Arg[0..n].
  701.     # x:=Arg[0], for i:=1 to n do ( x := x+Arg[i] ), return(x).
  702.     { var reg1 object* arg_i_ptr = rest_args_pointer;
  703.       var reg2 object x = NEXT(arg_i_ptr); # bisherige Summe
  704.       dotimesC(argcount,argcount, { x = N_N_plus_N(x,NEXT(arg_i_ptr)); } );
  705.       value1 = x; mv_count=1; set_args_end_pointer(rest_args_pointer);
  706.   } }
  707.  
  708. LISPFUN(minus,1,0,rest,nokey,0,NIL)
  709. # (- number {number}), CLTL S. 199
  710. # Methode:
  711. # (- x) extra.
  712. # (- x1 x2 x3 ... xn) = (- ...(- (- x1 x2) x3)... xn)
  713.   { var reg4 object* args_pointer = rest_args_pointer STACKop 1;
  714.     test_number_args(argcount,args_pointer); # Alle Argumente Zahlen?
  715.     if (argcount==0)
  716.       # unΣres Minus
  717.       { value1 = N_minus_N(Next(args_pointer)); }
  718.       else
  719.       # Methode:
  720.       # n+1 Argumente Arg[0..n].
  721.       # x:=Arg[0], for i:=1 to n do ( x := x-Arg[i] ), return(x).
  722.       { var reg1 object* arg_i_ptr = args_pointer;
  723.         var reg2 object x = NEXT(arg_i_ptr); # bisherige Differenz
  724.         dotimespC(argcount,argcount, { x = N_N_minus_N(x,NEXT(arg_i_ptr)); } );
  725.         value1 = x;
  726.       }
  727.     mv_count=1; set_args_end_pointer(args_pointer);
  728.   }
  729.  
  730. LISPFUN(mal,0,0,rest,nokey,0,NIL)
  731. # (* {number}), CLTL S. 199
  732. # Methode:
  733. # (*) = 1
  734. # (* x1 x2 x3 ... xn) = (* ...(* (* x1 x2) x3)... xn)
  735.   { if (argcount==0) { value1 = Fixnum_1; mv_count=1; return; }
  736.     argcount--;
  737.     test_number_args(argcount,rest_args_pointer); # Alle Argumente Zahlen?
  738.     # Methode:
  739.     # n+1 Argumente Arg[0..n].
  740.     # x:=Arg[0], for i:=1 to n do ( x := x*Arg[i] ), return(x).
  741.     { var reg1 object* arg_i_ptr = rest_args_pointer;
  742.       var reg2 object x = NEXT(arg_i_ptr); # bisheriges Produkt
  743.       dotimesC(argcount,argcount, { x = N_N_mal_N(x,NEXT(arg_i_ptr)); } );
  744.       value1 = x; mv_count=1; set_args_end_pointer(rest_args_pointer);
  745.   } }
  746.  
  747. LISPFUN(durch,1,0,rest,nokey,0,NIL)
  748. # (/ number {number}), CLTL S. 200
  749. # Methode:
  750. # (/ x) extra.
  751. # (/ x1 x2 x3 ... xn) = (/ ...(/ (/ x1 x2) x3)... xn)
  752.   { var reg4 object* args_pointer = rest_args_pointer STACKop 1;
  753.     test_number_args(argcount,args_pointer); # Alle Argumente Zahlen?
  754.     if (argcount==0)
  755.       # unΣres Durch
  756.       { value1 = N_durch_N(Next(args_pointer)); }
  757.       else
  758.       # Methode:
  759.       # n+1 Argumente Arg[0..n].
  760.       # x:=Arg[0], for i:=1 to n do ( x := x/Arg[i] ), return(x).
  761.       { var reg1 object* arg_i_ptr = args_pointer;
  762.         var reg2 object x = NEXT(arg_i_ptr); # bisherige Differenz
  763.         dotimespC(argcount,argcount, { x = N_N_durch_N(x,NEXT(arg_i_ptr)); } );
  764.         value1 = x;
  765.       }
  766.     mv_count=1; set_args_end_pointer(args_pointer);
  767.   }
  768.  
  769. LISPFUNN(einsplus,1)
  770. # (1+ number), CLTL S. 200
  771.   { var reg1 object x = popSTACK();
  772.     check_number(x);
  773.     value1 = N_1_plus_N(x); mv_count=1;
  774.   }
  775.  
  776. LISPFUNN(einsminus,1)
  777. # (1- number), CLTL S. 200
  778.   { var reg1 object x = popSTACK();
  779.     check_number(x);
  780.     value1 = N_minus1_plus_N(x); mv_count=1;
  781.   }
  782.  
  783. LISPFUNN(conjugate,1)
  784. # (CONJUGATE number), CLTL S. 201
  785.   { var reg1 object x = popSTACK();
  786.     check_number(x);
  787.     value1 = N_conjugate_N(x); mv_count=1;
  788.   }
  789.  
  790. LISPFUN(gcd,0,0,rest,nokey,0,NIL)
  791. # (GCD {integer}), CLTL S. 202
  792. # Methode:
  793. # (gcd) = 0
  794. # (gcd x) = (abs x)
  795. # (gcd x1 x2 x3 ... xn) = (gcd ...(gcd (gcd x1 x2) x3)... xn)
  796.   { if (argcount==0) { value1 = Fixnum_0; mv_count=1; return; }
  797.     argcount--;
  798.     test_integer_args(argcount,rest_args_pointer); # Alle Argumente ganze Zahlen?
  799.     if (argcount==0)
  800.       { value1 = I_abs_I(Next(rest_args_pointer)); }
  801.       else
  802.       # Methode:
  803.       # n+1 Argumente Arg[0..n].
  804.       # x:=Arg[0], for i:=1 to n do ( x := gcd(x,Arg[i]) ), return(x).
  805.       { var reg1 object* arg_i_ptr = rest_args_pointer;
  806.         var reg2 object x = NEXT(arg_i_ptr); # bisheriger ggT
  807.         dotimespC(argcount,argcount, { x = I_I_gcd_I(x,NEXT(arg_i_ptr)); } );
  808.         value1 = x;
  809.       }
  810.     mv_count=1; set_args_end_pointer(rest_args_pointer);
  811.   }
  812.  
  813. LISPFUN(xgcd,0,0,rest,nokey,0,NIL)
  814. # (XGCD {integer})
  815. # (XGCD x1 ... xn) liefert n+1 Werte: g = (gcd x1 ... xn), ein Integer >=0,
  816. # und n Integers u1,...,un mit g = u1*x1+...+un*xn.
  817. # Methode:
  818. # (xgcd) = 0
  819. # (xgcd x) = (abs x), (signum x)
  820. # (xgcd x1 x2 x3 ... xn) mit n>=2:
  821. #   (g,u[1],u[2]) := (xgcd x1 x2),
  822. #   fⁿr i=3,...,n:
  823. #     (g',u,v) := (xgcd g xi),
  824. #     (g,u[1],...,u[i]) := (g',u*u[1],...,u*u[i-1],v).
  825.   { if (argcount==0) { value1 = Fixnum_0; mv_count=1; return; }
  826.     argcount--;
  827.     test_integer_args(argcount,rest_args_pointer); # Alle Argumente ganze Zahlen?
  828.     if (argcount==0)
  829.       { var reg1 object arg = Next(rest_args_pointer);
  830.         if (R_minusp(arg))
  831.           { value1 = arg; value2 = Fixnum_minus1; }
  832.           else
  833.           { value1 = I_minus_I(arg); value2 = Fixnum_1; }
  834.         mv_count=2;
  835.       }
  836.       else
  837.       # Methode:
  838.       # n+1 Argumente Arg[0..n].
  839.       # (g,u,v):=xgcd(Arg[0],Arg[1]), Arg[0]:=u, Arg[1]:=v,
  840.       # for i:=2 to n do
  841.       #   ( (g,u,v):=xgcd(g,Arg[i]), Arg[i]:=v,
  842.       #     for j:=i-1 downto 0 do Arg[j]:=u*Arg[j],
  843.       #   ),
  844.       # return values(g,Arg[0],...,Arg[n]).
  845.       { var reg3 object* arg_i_ptr = rest_args_pointer;
  846.         var reg4 object g; # bisheriger ggT
  847.         {var reg2 object arg_0 = NEXT(arg_i_ptr);
  848.          var reg1 object arg_1 = Next(arg_i_ptr);
  849.          I_I_xgcd_I_I_I(arg_0,arg_1);
  850.          Before(arg_i_ptr) = STACK_2;
  851.         }
  852.         loop
  853.           { NEXT(arg_i_ptr) = STACK_1;
  854.             g = STACK_0; skipSTACK(3);
  855.             if (arg_i_ptr == args_end_pointer) break;
  856.             I_I_xgcd_I_I_I(g,Next(arg_i_ptr));
  857.            {var reg1 object* arg_j_ptr = arg_i_ptr;
  858.             do { var reg2 object arg_j = Before(arg_j_ptr);
  859.                  BEFORE(arg_j_ptr) = I_I_mal_I(STACK_2,arg_j);
  860.                }
  861.                until (arg_j_ptr == rest_args_pointer);
  862.           }}
  863.         value1 = g; # g als 1. Wert
  864.         # Beifaktoren als weitere Werte:
  865.         {var reg2 object* mvp = &value2;
  866.          var reg1 object* arg_i_ptr = rest_args_pointer;
  867.          if (argcount >= mv_limit-2) { fehler_mv_zuviel(S(xgcd)); }
  868.          mv_count = argcount+2;
  869.          dotimespC(argcount,argcount+1, { *mvp++ = NEXT(arg_i_ptr); } );
  870.       } }
  871.     set_args_end_pointer(rest_args_pointer);
  872.   }
  873.  
  874. LISPFUN(lcm,0,0,rest,nokey,0,NIL)
  875. # (LCM {integer})
  876. # Methode:
  877. # (lcm) = 1 (neutrales Element der lcm-Operation)
  878. # (lcm x) = (abs x)
  879. # (lcm x1 x2 x3 ... xn) = (lcm ...(lcm (lcm x1 x2) x3)... xn)
  880.   { if (argcount==0) { value1 = Fixnum_1; mv_count=1; return; }
  881.     argcount--;
  882.     test_integer_args(argcount,rest_args_pointer); # Alle Argumente ganze Zahlen?
  883.     if (argcount==0)
  884.       { value1 = I_abs_I(Next(rest_args_pointer)); }
  885.       else
  886.       # Methode:
  887.       # n+1 Argumente Arg[0..n].
  888.       # x:=Arg[0], for i:=1 to n do ( x := lcm(x,Arg[i]) ), return(x).
  889.       { var reg1 object* arg_i_ptr = rest_args_pointer;
  890.         var reg2 object x = NEXT(arg_i_ptr); # bisheriges kgV
  891.         dotimespC(argcount,argcount, { x = I_I_lcm_I(x,NEXT(arg_i_ptr)); } );
  892.         value1 = x;
  893.       }
  894.     mv_count=1; set_args_end_pointer(rest_args_pointer);
  895.   }
  896.  
  897. LISPFUNN(exp,1)
  898. # (EXP number), CLTL S. 203
  899.   { var reg1 object x = popSTACK();
  900.     check_number(x);
  901.     value1 = N_exp_N(x); mv_count=1;
  902.   }
  903.  
  904. LISPFUNN(expt,2)
  905. # (EXPT number number), CLTL S. 203
  906.   { var reg1 object x = STACK_1;
  907.     var reg1 object y = STACK_0;
  908.     check_number(x); check_number(y); skipSTACK(2);
  909.     value1 = N_N_expt_N(x,y); mv_count=1;
  910.   }
  911.  
  912. LISPFUN(log,1,1,norest,nokey,0,NIL)
  913. # (LOG number [base-number]), CLTL S. 204
  914.   { var reg1 object base = popSTACK();
  915.     var reg2 object arg = popSTACK();
  916.     check_number(arg);
  917.     if (eq(base,unbound))
  918.       # LOG mit einem Argument
  919.       { value1 = N_log_N(arg); }
  920.       else
  921.       # LOG mit zwei Argumenten
  922.       { check_number(base);
  923.         value1 = N_N_log_N(arg,base);
  924.       }
  925.     mv_count=1;
  926.   }
  927.  
  928. LISPFUNN(sqrt,1)
  929. # (SQRT number), CLTL S. 205
  930.   { var reg1 object x = popSTACK();
  931.     check_number(x);
  932.     value1 = N_sqrt_N(x); mv_count=1;
  933.   }
  934.  
  935. LISPFUNN(isqrt,1)
  936. # (ISQRT integer), CLTL S. 205
  937.   { var reg1 object x = popSTACK();
  938.     check_integer(x);
  939.     value1 = (I_isqrt_I(x), popSTACK()); mv_count=1;
  940.   }
  941.  
  942. LISPFUNN(abs,1)
  943. # (ABS number), CLTL S. 205
  944.   { var reg1 object x = popSTACK();
  945.     check_number(x);
  946.     value1 = N_abs_R(x); mv_count=1;
  947.   }
  948.  
  949. LISPFUNN(phase,1)
  950. # (PHASE number), CLTL S. 206
  951.   { var reg1 object x = popSTACK();
  952.     check_number(x);
  953.     value1 = N_phase_R(x); mv_count=1;
  954.   }
  955.  
  956. LISPFUNN(signum,1)
  957. # (SIGNUM number), CLTL S. 206
  958.   { var reg1 object x = popSTACK();
  959.     check_number(x);
  960.     value1 = N_signum_N(x); mv_count=1;
  961.   }
  962.  
  963. LISPFUNN(sin,1)
  964. # (SIN number), CLTL S. 207
  965.   { var reg1 object x = popSTACK();
  966.     check_number(x);
  967.     value1 = N_sin_N(x); mv_count=1;
  968.   }
  969.  
  970. LISPFUNN(cos,1)
  971. # (COS number), CLTL S. 207
  972.   { var reg1 object x = popSTACK();
  973.     check_number(x);
  974.     value1 = N_cos_N(x); mv_count=1;
  975.   }
  976.  
  977. LISPFUNN(tan,1)
  978. # (TAN number), CLTL S. 207
  979.   { var reg1 object x = popSTACK();
  980.     check_number(x);
  981.     value1 = N_tan_N(x); mv_count=1;
  982.   }
  983.  
  984. LISPFUNN(cis,1)
  985. # (CIS number), CLTL S. 207
  986.   { var reg1 object x = popSTACK();
  987.     check_number(x);
  988.     value1 = N_cis_N(x); mv_count=1;
  989.   }
  990.  
  991. LISPFUNN(asin,1)
  992. # (ASIN number), CLTL S. 207
  993.   { var reg1 object x = popSTACK();
  994.     check_number(x);
  995.     value1 = N_asin_N(x); mv_count=1;
  996.   }
  997.  
  998. LISPFUNN(acos,1)
  999. # (ACOS number), CLTL S. 207
  1000.   { var reg1 object x = popSTACK();
  1001.     check_number(x);
  1002.     value1 = N_acos_N(x); mv_count=1;
  1003.   }
  1004.  
  1005. LISPFUN(atan,1,1,norest,nokey,0,NIL)
  1006. # (ATAN number [real]), CLTL S. 207
  1007.   { var reg2 object arg2 = popSTACK();
  1008.     var reg1 object arg1 = popSTACK();
  1009.     if (eq(arg2,unbound))
  1010.       # 1 Argument
  1011.       { check_number(arg1);
  1012.         value1 = N_atan_N(arg1);
  1013.       }
  1014.       else
  1015.       # 2 Argumente
  1016.       { check_real(arg1); check_real(arg2);
  1017.         value1 = R_R_atan_R(arg2,arg1); # atan(X=arg2,Y=arg1)
  1018.       }
  1019.     mv_count=1;
  1020.   }
  1021.  
  1022. LISPFUNN(sinh,1)
  1023. # (SINH number), CLTL S. 209
  1024.   { var reg1 object x = popSTACK();
  1025.     check_number(x);
  1026.     value1 = N_sinh_N(x); mv_count=1;
  1027.   }
  1028.  
  1029. LISPFUNN(cosh,1)
  1030. # (COSH number), CLTL S. 209
  1031.   { var reg1 object x = popSTACK();
  1032.     check_number(x);
  1033.     value1 = N_cosh_N(x); mv_count=1;
  1034.   }
  1035.  
  1036. LISPFUNN(tanh,1)
  1037. # (TANH number), CLTL S. 209
  1038.   { var reg1 object x = popSTACK();
  1039.     check_number(x);
  1040.     value1 = N_tanh_N(x); mv_count=1;
  1041.   }
  1042.  
  1043. LISPFUNN(asinh,1)
  1044. # (ASINH number), CLTL S. 209
  1045.   { var reg1 object x = popSTACK();
  1046.     check_number(x);
  1047.     value1 = N_asinh_N(x); mv_count=1;
  1048.   }
  1049.  
  1050. LISPFUNN(acosh,1)
  1051. # (ACOSH number), CLTL S. 209
  1052.   { var reg1 object x = popSTACK();
  1053.     check_number(x);
  1054.     value1 = N_acosh_N(x); mv_count=1;
  1055.   }
  1056.  
  1057. LISPFUNN(atanh,1)
  1058. # (ATANH number), CLTL S. 209
  1059.   { var reg1 object x = popSTACK();
  1060.     check_number(x);
  1061.     value1 = N_atanh_N(x); mv_count=1;
  1062.   }
  1063.  
  1064. LISPFUN(float,1,1,norest,nokey,0,NIL)
  1065. # (FLOAT number [float]), CLTL S. 214
  1066.   { var reg2 object arg2 = popSTACK();
  1067.     var reg1 object arg1 = popSTACK();
  1068.     check_real(arg1);
  1069.     if (eq(arg2,unbound))
  1070.       # 1 Argument
  1071.       { value1 = R_float_F(arg1); }
  1072.       else
  1073.       # 2 Argumente
  1074.       { check_float(arg2); value1 = R_F_float_F(arg1,arg2); }
  1075.     mv_count=1;
  1076.   }
  1077.  
  1078. # UP: Wandelt ein Objekt in ein Float von gegebenem Typ um.
  1079. # coerce_float(obj,type)
  1080. # > obj: Objekt
  1081. # > type: Eines der Symbole
  1082. #         FLOAT, SHORT-FLOAT, SINGLE-FLOAT, DOUBLE-FLOAT, LONG-FLOAT
  1083. # > subr_self: Aufrufer (ein SUBR)
  1084. # < ergebnis: (coerce obj type)
  1085. # kann GC ausl÷sen
  1086.   global object coerce_float (object obj, object type);
  1087.   global object coerce_float(obj,type)
  1088.     var reg2 object obj;
  1089.     var reg1 object type;
  1090.     { check_real(obj);
  1091.       if (eq(type,S(short_float))) # SHORT-FLOAT
  1092.         { return R_to_SF(obj); }
  1093.       elif (eq(type,S(single_float))) # SINGLE-FLOAT
  1094.         { return R_to_FF(obj); }
  1095.       elif (eq(type,S(double_float))) # DOUBLE-FLOAT
  1096.         { return R_to_DF(obj); }
  1097.       elif (eq(type,S(long_float))) # LONG-FLOAT
  1098.         { return R_to_LF(obj,I_to_UL(O(LF_digits))); } # Default-Genauigkeit
  1099.       else # FLOAT
  1100.         { return R_float_F(obj); }
  1101.     }
  1102.  
  1103. LISPFUNN(rational,1)
  1104. # (RATIONAL real), CLTL S. 214
  1105.   { var reg1 object x = popSTACK();
  1106.     check_real(x);
  1107.     value1 = R_rational_RA(x); mv_count=1;
  1108.   }
  1109.  
  1110. LISPFUNN(rationalize,1)
  1111. # (RATIONALIZE real), CLTL S. 214
  1112.   { var reg1 object x = popSTACK();
  1113.     check_real(x);
  1114.     value1 = R_rationalize_RA(x); mv_count=1;
  1115.   }
  1116.  
  1117. LISPFUNN(numerator,1)
  1118. # (NUMERATOR rational), CLTL S. 215
  1119.   { var reg1 object x = popSTACK();
  1120.     check_rational(x);
  1121.     value1 = (RA_integerp(x) ? x : TheRatio(x)->rt_num); mv_count=1;
  1122.   }
  1123.  
  1124. LISPFUNN(denominator,1)
  1125. # (DENOMINATOR rational), CLTL S. 215
  1126.   { var reg1 object x = popSTACK();
  1127.     check_rational(x);
  1128.     value1 = (RA_integerp(x) ? Fixnum_1 : TheRatio(x)->rt_den); mv_count=1;
  1129.   }
  1130.  
  1131. LISPFUN(floor,1,1,norest,nokey,0,NIL)
  1132. # (FLOOR real [real]), CLTL S. 215
  1133.   { var reg1 object y = popSTACK();
  1134.     var reg2 object x = popSTACK();
  1135.     check_real(x);
  1136.     if (eq(y,unbound) || eq(y,Fixnum_1))
  1137.       # 1 Argument oder 2. Argument =1
  1138.       { R_floor_I_R(x); }
  1139.       else
  1140.       # 2 Argumente
  1141.       { check_real(y);
  1142.         R_R_floor_I_R(x,y);
  1143.       }
  1144.     # Stackaufbau: q, r.
  1145.     value1 = STACK_1; value2 = STACK_0; skipSTACK(2); mv_count=2;
  1146.   }
  1147.  
  1148. LISPFUN(ceiling,1,1,norest,nokey,0,NIL)
  1149. # (CEILING real [real]), CLTL S. 215
  1150.   { var reg1 object y = popSTACK();
  1151.     var reg2 object x = popSTACK();
  1152.     check_real(x);
  1153.     if (eq(y,unbound) || eq(y,Fixnum_1))
  1154.       # 1 Argument oder 2. Argument =1
  1155.       { R_ceiling_I_R(x); }
  1156.       else
  1157.       # 2 Argumente
  1158.       { check_real(y);
  1159.         R_R_ceiling_I_R(x,y);
  1160.       }
  1161.     # Stackaufbau: q, r.
  1162.     value1 = STACK_1; value2 = STACK_0; skipSTACK(2); mv_count=2;
  1163.   }
  1164.  
  1165. LISPFUN(truncate,1,1,norest,nokey,0,NIL)
  1166. # (TRUNCATE real [real]), CLTL S. 215
  1167.   { var reg1 object y = popSTACK();
  1168.     var reg2 object x = popSTACK();
  1169.     check_real(x);
  1170.     if (eq(y,unbound) || eq(y,Fixnum_1))
  1171.       # 1 Argument oder 2. Argument =1
  1172.       { R_truncate_I_R(x); }
  1173.       else
  1174.       # 2 Argumente
  1175.       { check_real(y);
  1176.         R_R_truncate_I_R(x,y);
  1177.       }
  1178.     # Stackaufbau: q, r.
  1179.     value1 = STACK_1; value2 = STACK_0; skipSTACK(2); mv_count=2;
  1180.   }
  1181.  
  1182. LISPFUN(round,1,1,norest,nokey,0,NIL)
  1183. # (ROUND real [real]), CLTL S. 215
  1184.   { var reg1 object y = popSTACK();
  1185.     var reg2 object x = popSTACK();
  1186.     check_real(x);
  1187.     if (eq(y,unbound) || eq(y,Fixnum_1))
  1188.       # 1 Argument oder 2. Argument =1
  1189.       { R_round_I_R(x); }
  1190.       else
  1191.       # 2 Argumente
  1192.       { check_real(y);
  1193.         R_R_round_I_R(x,y);
  1194.       }
  1195.     # Stackaufbau: q, r.
  1196.     value1 = STACK_1; value2 = STACK_0; skipSTACK(2); mv_count=2;
  1197.   }
  1198.  
  1199. LISPFUNN(mod,2)
  1200. # (MOD real real), CLTL S. 217
  1201.   { var reg1 object y = popSTACK();
  1202.     var reg2 object x = popSTACK();
  1203.     check_real(x);
  1204.     check_real(y);
  1205.     value1 = R_R_mod_R(x,y); mv_count=1;
  1206.   }
  1207.  
  1208. LISPFUNN(rem,2)
  1209. # (REM real real), CLTL S. 217
  1210.   { var reg1 object y = popSTACK();
  1211.     var reg2 object x = popSTACK();
  1212.     check_real(x);
  1213.     check_real(y);
  1214.     value1 = R_R_rem_R(x,y); mv_count=1;
  1215.   }
  1216.  
  1217. LISPFUN(ffloor,1,1,norest,nokey,0,NIL)
  1218. # (FFLOOR real [real]), CLTL S. 217
  1219.   { var reg1 object y = popSTACK();
  1220.     var reg2 object x = popSTACK();
  1221.     check_real(x);
  1222.     if (eq(y,unbound) || eq(y,Fixnum_1))
  1223.       # 1 Argument oder 2. Argument =1
  1224.       { R_ffloor_F_R(x); }
  1225.       else
  1226.       # 2 Argumente
  1227.       { check_real(y);
  1228.         R_R_ffloor_F_R(x,y);
  1229.       }
  1230.     # Stackaufbau: q, r.
  1231.     value1 = STACK_1; value2 = STACK_0; skipSTACK(2); mv_count=2;
  1232.   }
  1233.  
  1234. LISPFUN(fceiling,1,1,norest,nokey,0,NIL)
  1235. # (FCEILING real [real]), CLTL S. 217
  1236.   { var reg1 object y = popSTACK();
  1237.     var reg2 object x = popSTACK();
  1238.     check_real(x);
  1239.     if (eq(y,unbound) || eq(y,Fixnum_1))
  1240.       # 1 Argument oder 2. Argument =1
  1241.       { R_fceiling_F_R(x); }
  1242.       else
  1243.       # 2 Argumente
  1244.       { check_real(y);
  1245.         R_R_fceiling_F_R(x,y);
  1246.       }
  1247.     # Stackaufbau: q, r.
  1248.     value1 = STACK_1; value2 = STACK_0; skipSTACK(2); mv_count=2;
  1249.   }
  1250.  
  1251. LISPFUN(ftruncate,1,1,norest,nokey,0,NIL)
  1252. # (FTRUNCATE real [real]), CLTL S. 217
  1253.   { var reg1 object y = popSTACK();
  1254.     var reg2 object x = popSTACK();
  1255.     check_real(x);
  1256.     if (eq(y,unbound) || eq(y,Fixnum_1))
  1257.       # 1 Argument oder 2. Argument =1
  1258.       { R_ftruncate_F_R(x); }
  1259.       else
  1260.       # 2 Argumente
  1261.       { check_real(y);
  1262.         R_R_ftruncate_F_R(x,y);
  1263.       }
  1264.     # Stackaufbau: q, r.
  1265.     value1 = STACK_1; value2 = STACK_0; skipSTACK(2); mv_count=2;
  1266.   }
  1267.  
  1268. LISPFUN(fround,1,1,norest,nokey,0,NIL)
  1269. # (FROUND real [real]), CLTL S. 217
  1270.   { var reg1 object y = popSTACK();
  1271.     var reg2 object x = popSTACK();
  1272.     check_real(x);
  1273.     if (eq(y,unbound) || eq(y,Fixnum_1))
  1274.       # 1 Argument oder 2. Argument =1
  1275.       { R_fround_F_R(x); }
  1276.       else
  1277.       # 2 Argumente
  1278.       { check_real(y);
  1279.         R_R_fround_F_R(x,y);
  1280.       }
  1281.     # Stackaufbau: q, r.
  1282.     value1 = STACK_1; value2 = STACK_0; skipSTACK(2); mv_count=2;
  1283.   }
  1284.  
  1285. LISPFUNN(decode_float,1)
  1286. # (DECODE-FLOAT float), CLTL S. 218
  1287.   { var reg1 object f = popSTACK();
  1288.     check_float(f);
  1289.     F_decode_float_F_I_F(f);
  1290.     value1 = STACK_2; value2 = STACK_1; value3 = STACK_0; skipSTACK(3);
  1291.     mv_count=3;
  1292.   }
  1293.  
  1294. LISPFUNN(scale_float,2)
  1295. # (SCALE-FLOAT float integer), CLTL S. 218
  1296.   { var reg1 object f = STACK_1;
  1297.     var reg1 object i = STACK_0;
  1298.     check_float(f); check_integer(i); skipSTACK(2);
  1299.     value1 = F_I_scale_float_F(f,i); mv_count=1;
  1300.   }
  1301.  
  1302. LISPFUNN(float_radix,1)
  1303. # (FLOAT-RADIX float), CLTL S. 218
  1304.   { var reg1 object f = popSTACK();
  1305.     check_float(f);
  1306.     value1 = F_float_radix_I(f); mv_count=1;
  1307.   }
  1308.  
  1309. LISPFUN(float_sign,1,1,norest,nokey,0,NIL)
  1310. # (FLOAT-SIGN float [float]), CLTL S. 218
  1311.   { var reg2 object arg2 = popSTACK();
  1312.     var reg1 object arg1 = popSTACK();
  1313.     check_float(arg1);
  1314.     if (eq(arg2,unbound))
  1315.       # 1 Argument
  1316.       { value1 = F_float_sign_F(arg1); }
  1317.       else
  1318.       # 2 Argumente
  1319.       { check_float(arg2);
  1320.         value1 = F_F_float_sign_F(arg1,arg2);
  1321.       }
  1322.   }
  1323.  
  1324. LISPFUN(float_digits,1,1,norest,nokey,0,NIL)
  1325. # (FLOAT-DIGITS number [digits]), CLTL S. 218
  1326.   { var reg2 object arg2 = popSTACK();
  1327.     var reg3 object arg1 = popSTACK();
  1328.     if (eq(arg2,unbound))
  1329.       # 1 Argument: (FLOAT-DIGITS float)
  1330.       { check_float(arg1);
  1331.         value1 = F_float_digits_I(arg1);
  1332.       }
  1333.       else
  1334.       # 2 Argumente: (FLOAT-DIGITS number digits)
  1335.       { if (!posfixnump(arg2)) { fehler_digits(arg2); } # nicht notwendig Fixnum!??
  1336.        {var reg1 uintL d = posfixnum_to_L(arg2); # = I_to_UL(arg2); ??
  1337.         if (d==0) { fehler_digits(arg2); } # sollte >0 sein
  1338.         check_real(arg1);
  1339.         # arg1 in ein Float mit mindestens d Bits umwandeln:
  1340.         if (d > DF_mant_len+1)
  1341.           # -> Long-Float
  1342.           { d = ceiling(d,intDsize);
  1343.             if ((intCsize<32) && (d > (bitc(intCsize)-1))) { fehler_LF_toolong(); }
  1344.             value1 = R_to_LF(arg1,d);
  1345.           }
  1346.           else
  1347.           # ein Double-Float reicht
  1348.           if (d > FF_mant_len+1)
  1349.             # -> Double-Float
  1350.             { value1 = R_to_DF(arg1); }
  1351.             else
  1352.             # ein Single-Float reicht
  1353.             if (d > SF_mant_len+1)
  1354.               # -> Single-Float
  1355.               { value1 = R_to_FF(arg1); }
  1356.               else
  1357.               # ein Short-Float reicht
  1358.               { value1 = R_to_SF(arg1); }
  1359.       }}
  1360.     mv_count=1;
  1361.   }
  1362.  
  1363. LISPFUNN(float_precision,1)
  1364. # (FLOAT-PRECISION float), CLTL S. 218
  1365.   { var reg1 object f = popSTACK();
  1366.     check_float(f);
  1367.     value1 = F_float_precision_I(f); mv_count=1;
  1368.   }
  1369.  
  1370. LISPFUNN(integer_decode_float,1)
  1371. # (INTEGER-DECODE-FLOAT float), CLTL S. 218
  1372.   { var reg1 object f = popSTACK();
  1373.     check_float(f);
  1374.     F_integer_decode_float_I_I_I(f);
  1375.     value1 = STACK_2; value2 = STACK_1; value3 = STACK_0; skipSTACK(3);
  1376.     mv_count=3;
  1377.   }
  1378.  
  1379. LISPFUN(complex,1,1,norest,nokey,0,NIL)
  1380. # (COMPLEX real [real]), CLTL S. 220
  1381. # Abweichung von CLTL:
  1382. # Bei uns ist fⁿr reelle x stets (COMPLEX x) = x.
  1383. # Grund: Da▀ (COMPLEX 1) = 1 sein soll, zeigt, da▀ (COMPLEX x) als (COMPLEX x 0)
  1384. # zu interpretieren ist. Bei uns k÷nnen komplexe Zahlen einen Realteil
  1385. # und einen ImaginΣrteil verschiedenen Typs haben (vgl. CLTL, Seite 19),
  1386. # und es ist dann (COMPLEX x 0) = x.
  1387.   { var reg1 object arg2 = popSTACK();
  1388.     var reg2 object arg1 = popSTACK();
  1389.     check_real(arg1);
  1390.     if (eq(arg2,unbound))
  1391.       # 1 Argument
  1392.       { value1 = arg1; }
  1393.       else
  1394.       # 2 Argumente
  1395.       { check_real(arg2);
  1396.         value1 = R_R_complex_N(arg1,arg2);
  1397.       }
  1398.     mv_count=1;
  1399.   }
  1400.  
  1401. LISPFUNN(realpart,1)
  1402. # (REALPART number), CLTL S. 220
  1403.   { var reg1 object x = popSTACK();
  1404.     check_number(x);
  1405.     value1 = N_realpart_R(x); mv_count=1;
  1406.   }
  1407.  
  1408. LISPFUNN(imagpart,1)
  1409. # (IMAGPART number), CLTL S. 220
  1410.   { var reg1 object x = popSTACK();
  1411.     check_number(x);
  1412.     value1 = N_imagpart_R(x); mv_count=1;
  1413.   }
  1414.  
  1415. LISPFUN(logior,0,0,rest,nokey,0,NIL)
  1416. # (LOGIOR {integer}), CLTL S. 221
  1417. # Methode:
  1418. # (logior) = 0
  1419. # (logior x1 x2 x3 ... xn) = (logior ...(logior (logior x1 x2) x3)... xn)
  1420.   { if (argcount==0) { value1 = Fixnum_0; mv_count=1; return; }
  1421.     argcount--;
  1422.     test_integer_args(argcount,rest_args_pointer); # Alle Argumente ganze Zahlen?
  1423.     # Methode:
  1424.     # n+1 Argumente Arg[0..n].
  1425.     # x:=Arg[0], for i:=1 to n do ( x := logior(x,Arg[i]) ), return(x).
  1426.     { var reg1 object* arg_i_ptr = rest_args_pointer;
  1427.       var reg2 object x = NEXT(arg_i_ptr); # bisheriges Oder
  1428.       dotimesC(argcount,argcount, { x = I_I_logior_I(x,NEXT(arg_i_ptr)); } );
  1429.       value1 = x; mv_count=1; set_args_end_pointer(rest_args_pointer);
  1430.   } }
  1431.  
  1432. LISPFUN(logxor,0,0,rest,nokey,0,NIL)
  1433. # (LOGXOR {integer}), CLTL S. 221
  1434. # Methode:
  1435. # (logxor) = 0
  1436. # (logxor x1 x2 x3 ... xn) = (logxor ...(logxor (logxor x1 x2) x3)... xn)
  1437.   { if (argcount==0) { value1 = Fixnum_0; mv_count=1; return; }
  1438.     argcount--;
  1439.     test_integer_args(argcount,rest_args_pointer); # Alle Argumente ganze Zahlen?
  1440.     # Methode:
  1441.     # n+1 Argumente Arg[0..n].
  1442.     # x:=Arg[0], for i:=1 to n do ( x := logxor(x,Arg[i]) ), return(x).
  1443.     { var reg1 object* arg_i_ptr = rest_args_pointer;
  1444.       var reg2 object x = NEXT(arg_i_ptr); # bisheriges Xor
  1445.       dotimesC(argcount,argcount, { x = I_I_logxor_I(x,NEXT(arg_i_ptr)); } );
  1446.       value1 = x; mv_count=1; set_args_end_pointer(rest_args_pointer);
  1447.   } }
  1448.  
  1449. LISPFUN(logand,0,0,rest,nokey,0,NIL)
  1450. # (LOGAND {integer}), CLTL S. 221
  1451. # Methode:
  1452. # (logand) = -1
  1453. # (logand x1 x2 x3 ... xn) = (logand ...(logand (logand x1 x2) x3)... xn)
  1454.   { if (argcount==0) { value1 = Fixnum_minus1; mv_count=1; return; }
  1455.     argcount--;
  1456.     test_integer_args(argcount,rest_args_pointer); # Alle Argumente ganze Zahlen?
  1457.     # Methode:
  1458.     # n+1 Argumente Arg[0..n].
  1459.     # x:=Arg[0], for i:=1 to n do ( x := logand(x,Arg[i]) ), return(x).
  1460.     { var reg1 object* arg_i_ptr = rest_args_pointer;
  1461.       var reg2 object x = NEXT(arg_i_ptr); # bisheriges And
  1462.       dotimesC(argcount,argcount, { x = I_I_logand_I(x,NEXT(arg_i_ptr)); } );
  1463.       value1 = x; mv_count=1; set_args_end_pointer(rest_args_pointer);
  1464.   } }
  1465.  
  1466. LISPFUN(logeqv,0,0,rest,nokey,0,NIL)
  1467. # (LOGEQV {integer}), CLTL S. 221
  1468. # Methode:
  1469. # (logeqv) = -1
  1470. # (logeqv x1 x2 x3 ... xn) = (logeqv ...(logeqv (logeqv x1 x2) x3)... xn)
  1471.   { if (argcount==0) { value1 = Fixnum_minus1; mv_count=1; return; }
  1472.     argcount--;
  1473.     test_integer_args(argcount,rest_args_pointer); # Alle Argumente ganze Zahlen?
  1474.     # Methode:
  1475.     # n+1 Argumente Arg[0..n].
  1476.     # x:=Arg[0], for i:=1 to n do ( x := logeqv(x,Arg[i]) ), return(x).
  1477.     { var reg1 object* arg_i_ptr = rest_args_pointer;
  1478.       var reg2 object x = NEXT(arg_i_ptr); # bisheriges Zwischen-EQV
  1479.       dotimesC(argcount,argcount, { x = I_I_logeqv_I(x,NEXT(arg_i_ptr)); } );
  1480.       value1 = x; mv_count=1; set_args_end_pointer(rest_args_pointer);
  1481.   } }
  1482.  
  1483. LISPFUNN(lognand,2)
  1484. # (LOGNAND integer integer), CLTL S. 221
  1485.   { var reg2 object x = STACK_1;
  1486.     var reg1 object y = STACK_0;
  1487.     check_integer(x); check_integer(y); skipSTACK(2);
  1488.     value1 = I_I_lognand_I(x,y); mv_count=1;
  1489.   }
  1490.  
  1491. LISPFUNN(lognor,2)
  1492. # (LOGNOR integer integer), CLTL S. 221
  1493.   { var reg2 object x = STACK_1;
  1494.     var reg1 object y = STACK_0;
  1495.     check_integer(x); check_integer(y); skipSTACK(2);
  1496.     value1 = I_I_lognor_I(x,y); mv_count=1;
  1497.   }
  1498.  
  1499. LISPFUNN(logandc1,2)
  1500. # (LOGANDC1 integer integer), CLTL S. 221
  1501.   { var reg2 object x = STACK_1;
  1502.     var reg1 object y = STACK_0;
  1503.     check_integer(x); check_integer(y); skipSTACK(2);
  1504.     value1 = I_I_logandc1_I(x,y); mv_count=1;
  1505.   }
  1506.  
  1507. LISPFUNN(logandc2,2)
  1508. # (LOGANDC2 integer integer), CLTL S. 221
  1509.   { var reg2 object x = STACK_1;
  1510.     var reg1 object y = STACK_0;
  1511.     check_integer(x); check_integer(y); skipSTACK(2);
  1512.     value1 = I_I_logandc2_I(x,y); mv_count=1;
  1513.   }
  1514.  
  1515. LISPFUNN(logorc1,2)
  1516. # (LOGORC1 integer integer), CLTL S. 221
  1517.   { var reg2 object x = STACK_1;
  1518.     var reg1 object y = STACK_0;
  1519.     check_integer(x); check_integer(y); skipSTACK(2);
  1520.     value1 = I_I_logorc1_I(x,y); mv_count=1;
  1521.   }
  1522.  
  1523. LISPFUNN(logorc2,2)
  1524. # (LOGORC2 integer integer), CLTL S. 221
  1525.   { var reg2 object x = STACK_1;
  1526.     var reg1 object y = STACK_0;
  1527.     check_integer(x); check_integer(y); skipSTACK(2);
  1528.     value1 = I_I_logorc2_I(x,y); mv_count=1;
  1529.   }
  1530.  
  1531. LISPFUNN(boole,3)
  1532. # (BOOLE op integer integer), CLTL S. 222
  1533.   { var reg3 object op = STACK_2; # Operator, kein Typtest
  1534.     var reg2 object x = STACK_1;
  1535.     var reg1 object y = STACK_0;
  1536.     check_integer(x); check_integer(y); skipSTACK(3);
  1537.     value1 = OP_I_I_boole_I(op,x,y); mv_count=1;
  1538.   }
  1539.  
  1540. LISPFUNN(lognot,1)
  1541. # (LOGNOT integer), CLTL S. 223
  1542.   { var reg1 object x = popSTACK();
  1543.     check_integer(x);
  1544.     value1 = I_lognot_I(x); mv_count=1;
  1545.   }
  1546.  
  1547. LISPFUNN(logtest,2)
  1548. # (LOGTEST integer integer), CLTL S. 223
  1549.   { var reg2 object x = STACK_1;
  1550.     var reg1 object y = STACK_0;
  1551.     check_integer(x); check_integer(y); skipSTACK(2);
  1552.     value1 = (I_I_logtest(x,y) ? T : NIL); mv_count=1;
  1553.   }
  1554.  
  1555. LISPFUNN(logbitp,2)
  1556. # (LOGBITP integer integer), CLTL S. 224
  1557.   { var reg2 object x = STACK_1;
  1558.     var reg1 object y = STACK_0;
  1559.     check_integer(x); check_integer(y); skipSTACK(2);
  1560.     value1 = (I_I_logbitp(x,y) ? T : NIL); mv_count=1;
  1561.   }
  1562.  
  1563. LISPFUNN(ash,2)
  1564. # (ASH integer integer), CLTL S. 224
  1565.   { var reg2 object x = STACK_1;
  1566.     var reg1 object y = STACK_0;
  1567.     check_integer(x); check_integer(y); skipSTACK(2);
  1568.     value1 = I_I_ash_I(x,y); mv_count=1;
  1569.   }
  1570.  
  1571. LISPFUNN(logcount,1)
  1572. # (LOGCOUNT integer), CLTL S. 224
  1573.   { var reg1 object x = popSTACK();
  1574.     check_integer(x);
  1575.     value1 = I_logcount_I(x); mv_count=1;
  1576.   }
  1577.  
  1578. LISPFUNN(integer_length,1)
  1579. # (INTEGER-LENGTH integer), CLTL S. 224
  1580.   { var reg1 object x = popSTACK();
  1581.     check_integer(x);
  1582.     value1 = I_integer_length_I(x); mv_count=1;
  1583.   }
  1584.  
  1585. LISPFUNN(byte,2)
  1586. # (BYTE size position), CLTL S. 225
  1587.   { var reg2 object s = STACK_1;
  1588.     var reg1 object p = STACK_0;
  1589.     skipSTACK(2);
  1590.     value1 = I_I_Byte(s,p); mv_count=1; # Typprⁿfungen dort. Wieso Fixnums??
  1591.   }
  1592.  
  1593. LISPFUNN(bytesize,1)
  1594. # (BYTE-SIZE bytespec), CLTL S. 226
  1595.   { var reg1 object b = popSTACK();
  1596.     value1 = Byte_size(b); mv_count=1; # Typprⁿfung dort
  1597.   }
  1598.  
  1599. LISPFUNN(byteposition,1)
  1600. # (BYTE-POSITION bytespec), CLTL S. 226
  1601.   { var reg1 object b = popSTACK();
  1602.     value1 = Byte_position(b); mv_count=1; # Typprⁿfung dort
  1603.   }
  1604.  
  1605. LISPFUNN(ldb,2)
  1606. # (LDB bytespec integer), CLTL S. 226
  1607.   { var reg2 object b = STACK_1; # Typprⁿfung erfolgt spΣter
  1608.     var reg1 object x = STACK_0;
  1609.     check_integer(x); skipSTACK(2);
  1610.     value1 = I_Byte_ldb_I(x,b); mv_count=1;
  1611.   }
  1612.  
  1613. LISPFUNN(ldb_test,2)
  1614. # (LDB-TEST bytespec integer), CLTL S. 226
  1615.   { var reg2 object b = STACK_1; # Typprⁿfung erfolgt spΣter
  1616.     var reg1 object x = STACK_0;
  1617.     check_integer(x); skipSTACK(2);
  1618.     value1 = (I_Byte_ldb_test(x,b) ? T : NIL); mv_count=1;
  1619.   }
  1620.  
  1621. LISPFUNN(mask_field,2)
  1622. # (MASK_FIELD bytespec integer), CLTL S. 226
  1623.   { var reg2 object b = STACK_1; # Typprⁿfung erfolgt spΣter
  1624.     var reg1 object x = STACK_0;
  1625.     check_integer(x); skipSTACK(2);
  1626.     value1 = I_Byte_mask_field_I(x,b); mv_count=1;
  1627.   }
  1628.  
  1629. LISPFUNN(dpb,3)
  1630. # (DPB integer bytespec integer), CLTL S. 227
  1631.   { var reg2 object x = STACK_2;
  1632.     var reg3 object b = STACK_1; # Typprⁿfung erfolgt spΣter
  1633.     var reg1 object y = STACK_0;
  1634.     check_integer(x); check_integer(y); skipSTACK(3);
  1635.     value1 = I_I_Byte_dpb_I(x,y,b); mv_count=1;
  1636.   }
  1637.  
  1638. LISPFUNN(deposit_field,3)
  1639. # (DEPOSIT-FIELD integer bytespec integer), CLTL S. 227
  1640.   { var reg2 object x = STACK_2;
  1641.     var reg3 object b = STACK_1; # Typprⁿfung erfolgt spΣter
  1642.     var reg1 object y = STACK_0;
  1643.     check_integer(x); check_integer(y); skipSTACK(3);
  1644.     value1 = I_I_Byte_deposit_field_I(x,y,b); mv_count=1;
  1645.   }
  1646.  
  1647. # ▄berprⁿft ein optionales Random-State-Argument obj.
  1648. # check_random_state(obj)
  1649. # > obj: optionales Random-State-Argument
  1650. # > subr_self: Aufrufer (ein SUBR)
  1651. # < ergebnis: das gemeinte Random-State
  1652.   local object check_random_state (object obj);
  1653.   local object check_random_state(obj)
  1654.     var reg1 object obj;
  1655.     { if (!eq(obj,unbound))
  1656.         # angegeben -> mu▀ Random-State sein:
  1657.         { if (random_state_p(obj))
  1658.             { return obj; }
  1659.             else
  1660.             { pushSTACK(obj); # Wert fⁿr Slot DATUM von TYPE-ERROR
  1661.               pushSTACK(S(random_state)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  1662.               pushSTACK(obj);
  1663.               pushSTACK(TheSubr(subr_self)->name);
  1664.               fehler(type_error,
  1665.                      DEUTSCH ? "~: Argument mu▀ ein Random-State sein, nicht ~" :
  1666.                      ENGLISH ? "~: argument should be a random-state, not ~" :
  1667.                      FRANCAIS ? "~ : L'argument doit Ωtre un ½random-state╗ et non ~." :
  1668.                      ""
  1669.                     );
  1670.         }   }
  1671.         else
  1672.         # nicht angegeben -> Default aus *RANDOM-STATE*
  1673.         { obj = Symbol_value(S(random_state_stern)); # Wert von *RANDOM-STATE*
  1674.           if (random_state_p(obj))
  1675.             { return obj; }
  1676.             else
  1677.             { pushSTACK(obj); # Wert fⁿr Slot DATUM von TYPE-ERROR
  1678.               pushSTACK(S(random_state)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  1679.               pushSTACK(obj);
  1680.               pushSTACK(S(random_state_stern));
  1681.               pushSTACK(TheSubr(subr_self)->name);
  1682.               fehler(type_error,
  1683.                      DEUTSCH ? "~: Der Wert von ~ sollte ein Random-State sein, nicht ~" :
  1684.                      ENGLISH ? "~: the value of ~ should be a random-state, not ~" :
  1685.                      FRANCAIS ? "~ : La valeur de ~ devrait Ωtre un ½random-state╗ et non ~." :
  1686.                      ""
  1687.                     );
  1688.         }   }
  1689.     }
  1690.  
  1691. LISPFUN(random,1,1,norest,nokey,0,NIL)
  1692. # (RANDOM number [state]), CLTL S. 228
  1693.   { var reg1 object x = STACK_1;
  1694.     var reg2 object r = check_random_state(STACK_0);
  1695.     skipSTACK(2);
  1696.     check_real(x); # x mu▀ eine reelle Zahl sein, >0 und Float oder Integer
  1697.     if (R_plusp(x))
  1698.       { if (R_floatp(x)) { value1 = F_random_F(r,x); mv_count=1; return; }
  1699.         elif (RA_integerp(x)) { value1 = I_random_I(r,x); mv_count=1; return; }
  1700.       }
  1701.     pushSTACK(x); # Wert fⁿr Slot DATUM von TYPE-ERROR
  1702.     pushSTACK(O(type_random_arg)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  1703.     pushSTACK(x); pushSTACK(S(random));
  1704.     fehler(type_error,
  1705.            DEUTSCH ? "~: Argument mu▀ positiv und Integer oder Float sein, nicht ~" :
  1706.            ENGLISH ? "~: argument should be positive and an integer or float, not ~" :
  1707.            FRANCAIS ? "~ : L'argument doit Ωtre positif et de type entier ou flottant et non ~." :
  1708.            ""
  1709.           );
  1710.   }
  1711.  
  1712. # make_random_state(r) liefert ein neues Random-State mit Initialzustand
  1713. # - zufΣllig, falls r=T,
  1714. # - aus Random-State *RANDOM-STATE*, falls r=NIL oder r=unbound,
  1715. # - aus Random-State r selbst, sonst.
  1716. # kann GC ausl÷sen
  1717.   local object make_random_state (object r);
  1718.   local object make_random_state(r)
  1719.     var reg2 object r;
  1720.     { var reg4 uint32 seed_hi;
  1721.       var reg5 uint32 seed_lo;
  1722.       if (eq(r,T))
  1723.         # mit Random-Bits vom Betriebssystem initialisieren:
  1724.         {
  1725.           #if defined(ATARI)
  1726.           seed_lo = highlow32(GEMDOS_GetDate(),GEMDOS_GetTime()); # 16+16 zufΣllige Bits
  1727.           seed_hi = XBIOS_Random(); # 24 Bit zufΣllig vom XBIOS, vorne 8 Nullbits
  1728.           #elif defined(AMIGAOS)
  1729.           seed_lo = get_real_time(); # Uhrzeit
  1730.           seed_hi = FindTask(NULL); # Pointer auf eigene Task
  1731.           #elif defined(MSDOS) || defined(RISCOS)
  1732.           # Keine Zufallszahlen, keine PID, nichts ZufΣlliges da.
  1733.           seed_lo = get_real_time(); # Uhrzeit, 100 Hz
  1734.           begin_system_call(); seed_hi = time(NULL); end_system_call(); # Uhrzeit, 1 Hz
  1735.           #elif defined(UNIX)
  1736.           #ifdef TIME_UNIX
  1737.           var reg1 internal_time* real_time = get_real_time(); # Uhrzeit
  1738.           seed_lo = highlow32(real_time->tv_sec,real_time->tv_usec); # 16+16 zufΣllige Bits
  1739.           #endif
  1740.           #ifdef TIME_UNIX_TIMES
  1741.           seed_lo = get_real_time(); # Uhrzeit, CLK_TCK Hz
  1742.           #endif
  1743.           seed_hi = (rand() # zufΣllige 31 Bit (bei UNIX_BSD) bzw. 16 Bit (bei UNIX_SYSV)
  1744.                            << 8) ^ (uintL)(getpid()); # ca. 8 Bit von der Process ID
  1745.           #else
  1746.           #error "make_random_state() anpassen!"
  1747.           #endif
  1748.         }
  1749.         else
  1750.         { # Random-State ⁿberprⁿfen:
  1751.           r = check_random_state( (eq(r,NIL) ? unbound : r) );
  1752.           # dessen Zustand herausholen:
  1753.          {var reg3 object seed = The_Random_state(r)->random_state_seed;
  1754.           var reg1 uintD* seedMSDptr = (uintD*)(&TheSbvector(seed)->data[0]);
  1755.           seed_hi = get_32_Dptr(seedMSDptr);
  1756.           seed_lo = get_32_Dptr(&seedMSDptr[32/intDsize]);
  1757.         }}
  1758.       # neuen Zustands-Bitvektor holen und fⁿllen:
  1759.       {var reg3 object seed = allocate_bit_vector(64);
  1760.        var reg1 uintD* seedMSDptr = (uintD*)(&TheSbvector(seed)->data[0]);
  1761.        set_32_Dptr(seedMSDptr,seed_hi);
  1762.        set_32_Dptr(&seedMSDptr[32/intDsize],seed_lo);
  1763.        pushSTACK(seed);
  1764.       }
  1765.       {var reg1 object state = allocate_random_state(); # neuen Random-State
  1766.        The_Random_state(state)->random_state_seed = popSTACK(); # mit Bit-Vektor fⁿllen
  1767.        return state;
  1768.     } }
  1769.  
  1770. LISPFUN(make_random_state,0,1,norest,nokey,0,NIL)
  1771. # (MAKE-RANDOM-STATE [state]), CLTL S. 230
  1772.   { value1 = make_random_state(popSTACK()); mv_count=1; }
  1773.  
  1774. LISPFUNN(fakultaet,1)
  1775. # (! integer)
  1776.   { var reg1 object x = popSTACK();
  1777.     check_integer(x);
  1778.     if (!posfixnump(x))
  1779.       { pushSTACK(x); # Wert fⁿr Slot DATUM von TYPE-ERROR
  1780.         pushSTACK(O(type_posfixnum)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  1781.         pushSTACK(x); pushSTACK(TheSubr(subr_self)->name);
  1782.         fehler(type_error,
  1783.                DEUTSCH ? "~ : Argument mu▀ ein Fixnum >=0 sein, nicht ~" :
  1784.                ENGLISH ? "~ : argument should be a fixnum >=0, not ~" :
  1785.                FRANCAIS ? "~ : L'argument doit Ωtre de type FIXNUM positif ou zΘro et non ~." :
  1786.                ""
  1787.               );
  1788.       }
  1789.     # x ist ein Fixnum >=0.
  1790.     value1 = FN_fak_I(x); mv_count=1;
  1791.   }
  1792.  
  1793. LISPFUNN(exquo,2)
  1794. # (EXQUO integer integer) dividiert zwei Integers. Die Division mu▀ aufgehen.
  1795. # (EXQUO x y) == (THE INTEGER (/ (THE INTEGER x) (THE INTEGER y)))
  1796.   { var reg2 object x = STACK_1;
  1797.     var reg1 object y = STACK_0;
  1798.     check_integer(x); check_integer(y); skipSTACK(2);
  1799.     value1 = I_I_exquo_I(x,y); mv_count=1;
  1800.   }
  1801.  
  1802. LISPFUNN(long_float_digits,0)
  1803. # (LONG-FLOAT-DIGITS) liefert die Default-Bitzahl von Long-Floats.
  1804.   { value1 = UL_to_I(intDsize * I_to_UL(O(LF_digits))); mv_count=1; }
  1805.  
  1806. # Setzt die Default-Long-Float-LΣnge auf den Wert len (>= LF_minlen).
  1807. # set_lf_digits(len);
  1808. # kann GC ausl÷sen
  1809.   local void set_lf_digits (uintC len);
  1810.   local void set_lf_digits(len)
  1811.     var reg3 uintC len;
  1812.     { O(LF_digits) = UL_to_I(len);
  1813.       # MOST-POSITIVE-LONG-FLOAT und MOST-NEGATIVE-LONG-FLOAT :
  1814.       { # Exponent so gro▀ wie m÷glich, Mantisse 1...1
  1815.         var reg1 object x = allocate_lfloat(len,LF_exp_high,0);
  1816.         fill_loop_up(&TheLfloat(x)->data[0],len,~(uintD)0);
  1817.         define_variable(S(most_positive_long_float),x);
  1818.         x = LF_minus_LF(x);
  1819.         define_variable(S(most_negative_long_float),x);
  1820.       }
  1821.       # LEAST-POSITIVE-LONG-FLOAT und LEAST-NEGATIVE-LONG-FLOAT :
  1822.       { # Exponent so klein wie m÷glich, Mantisse 10...0
  1823.         var reg2 object x = allocate_lfloat(len,LF_exp_low,0);
  1824.         var reg1 uintD* ptr = &TheLfloat(x)->data[0];
  1825.         *ptr++ = bit(intDsize-1);
  1826.         clear_loop_up(ptr,len-1);
  1827.         define_variable(S(least_positive_long_float),x);
  1828.         x = LF_minus_LF(x);
  1829.         define_variable(S(least_negative_long_float),x);
  1830.       }
  1831.       # LONG-FLOAT-EPSILON = 2^-16n*(1+2^(1-16n)) :
  1832.       { # Exponent 1-16n, Mantisse 10...01
  1833.         var reg2 object x = allocate_lfloat(len,LF_exp_mid+1-intDsize*(uintL)len,0);
  1834.         var reg1 uintD* ptr = &TheLfloat(x)->data[0];
  1835.         *ptr++ = bit(intDsize-1);
  1836.         ptr = clear_loop_up(ptr,len-2);
  1837.         *ptr = bit(0);
  1838.         define_variable(S(long_float_epsilon),x);
  1839.       }
  1840.       # LONG-FLOAT-NEGATIVE-EPSILON = 2^(-16n-1)*(1+2^(1-16n)) :
  1841.       { # Exponent -16n, Mantisse 10...01
  1842.         var reg2 object x = allocate_lfloat(len,LF_exp_mid-intDsize*(uintL)len,0);
  1843.         var reg1 uintD* ptr = &TheLfloat(x)->data[0];
  1844.         *ptr++ = bit(intDsize-1);
  1845.         ptr = clear_loop_up(ptr,len-2);
  1846.         *ptr = bit(0);
  1847.         define_variable(S(long_float_negative_epsilon),x);
  1848.       # PI :
  1849.         x = O(pi) = pi_F_float_F(x);
  1850.         define_variable(S(pi),x);
  1851.       # SYS::*INHIBIT-FLOATING-POINT-UNDERFLOW* := NIL
  1852.         define_variable(S(inhibit_floating_point_underflow),NIL);
  1853.       }
  1854.     }
  1855.  
  1856. LISPFUNN(set_long_float_digits,1)
  1857. # (SETF (LONG-FLOAT-DIGITS) digits) = (SYS::%SET-LONG-FLOAT-DIGITS digits)
  1858.   { var reg2 object arg = STACK_0;
  1859.     if (!posfixnump(arg)) { fehler_digits(arg); } # nicht notwendig Fixnum!??
  1860.    {var reg1 uintL d = posfixnum_to_L(arg); # = I_to_UL(arg); ??
  1861.     if (d==0) { fehler_digits(arg); } # sollte >0 sein
  1862.     d = ceiling(d,intDsize);
  1863.     if ((intCsize<32) && (d > (bitc(intCsize)-1))) { fehler_LF_toolong(); }
  1864.     if (d < LF_minlen) { d = LF_minlen; } # d>=LF_minlen erzwingen
  1865.     set_lf_digits(d);
  1866.     value1 = popSTACK(); mv_count=1; # digits als Wert
  1867.   }}
  1868.  
  1869. # UP fⁿr LOG2 und LOG10: Logarithmus des Fixnums x mit mindestens digits
  1870. # Bits berechnen und - wenn n÷tig - den Wert in *objptr aktualisieren.
  1871.   local object log_digits (object x, object digits, object* objptr);
  1872.   local object log_digits(x,digits,objptr)
  1873.     var reg1 object x;
  1874.     var reg1 object digits;
  1875.     var reg1 object* objptr;
  1876.     { # digits-Argument ⁿberprⁿfen:
  1877.       if (!posfixnump(digits)) { fehler_digits(digits); } # nicht notwendig Fixnum!??
  1878.      {var reg1 uintL d = posfixnum_to_L(digits); # = I_to_UL(digits); ??
  1879.       if (d==0) { fehler_digits(digits); } # sollte >0 sein
  1880.       # bisher bekannten Wert holen:
  1881.       { var reg1 object ln_x = *objptr;
  1882.         # ln_x in ein Float mit mindestens d Bits umwandeln:
  1883.         if (d > DF_mant_len+1)
  1884.           # -> Long-Float
  1885.           { d = ceiling(d,intDsize);
  1886.             if ((intCsize<32) && (d > (bitc(intCsize)-1))) { fehler_LF_toolong(); }
  1887.            {var reg1 uintC len = TheLfloat(ln_x)->len; # vorhandene LΣnge
  1888.             if (d < len) { return LF_shorten_LF(ln_x,d); }
  1889.             if (d == len) { return ln_x; }
  1890.             # gewⁿnschte > vorhandene LΣnge -> mu▀ nachberechnen:
  1891.             return *objptr = R_ln_R(I_to_LF(x,d)); # (ln x) als LF mit d Digits berechnen
  1892.           }}
  1893.           else
  1894.           # ein Double-Float reicht
  1895.           if (d > FF_mant_len+1)
  1896.             # -> Double-Float
  1897.             { return LF_to_DF(ln_x); }
  1898.             else
  1899.             # ein Single-Float reicht
  1900.             if (d > SF_mant_len+1)
  1901.               # -> Single-Float
  1902.               { return LF_to_FF(ln_x); }
  1903.               else
  1904.               # ein Short-Float reicht
  1905.               { return LF_to_SF(ln_x); }
  1906.     }}}
  1907.  
  1908. LISPFUNN(log2,1)
  1909. # (SYS::LOG2 digits) liefert ln(2) mit mindestens digits Bits.
  1910.   { value1 = log_digits(fixnum(2),popSTACK(),&O(LF_ln2));
  1911.     mv_count=1;
  1912.   }
  1913.  
  1914. LISPFUNN(log10,1)
  1915. # (SYS::LOG10 digits) liefert ln(10) mit mindestens digits Bits.
  1916.   { value1 = log_digits(fixnum(10),popSTACK(),&O(LF_ln10));
  1917.     mv_count=1;
  1918.   }
  1919.  
  1920.  
  1921. # ============================================================================ #
  1922. #                             Initialisierung
  1923.  
  1924. # Mantisse von pi :
  1925.   local uintD pi_mantisse [2048/intDsize] =
  1926.     { D(0xC9,0x0F,0xDA,0xA2,) D(0x21,0x68,0xC2,0x34,) D(0xC4,0xC6,0x62,0x8B,)
  1927.       D(0x80,0xDC,0x1C,0xD1,) D(0x29,0x02,0x4E,0x08,) D(0x8A,0x67,0xCC,0x74,)
  1928.       D(0x02,0x0B,0xBE,0xA6,) D(0x3B,0x13,0x9B,0x22,) D(0x51,0x4A,0x08,0x79,)
  1929.       D(0x8E,0x34,0x04,0xDD,) D(0xEF,0x95,0x19,0xB3,) D(0xCD,0x3A,0x43,0x1B,)
  1930.       D(0x30,0x2B,0x0A,0x6D,) D(0xF2,0x5F,0x14,0x37,) D(0x4F,0xE1,0x35,0x6D,)
  1931.       D(0x6D,0x51,0xC2,0x45,) D(0xE4,0x85,0xB5,0x76,) D(0x62,0x5E,0x7E,0xC6,)
  1932.       D(0xF4,0x4C,0x42,0xE9,) D(0xA6,0x37,0xED,0x6B,) D(0x0B,0xFF,0x5C,0xB6,)
  1933.       D(0xF4,0x06,0xB7,0xED,) D(0xEE,0x38,0x6B,0xFB,) D(0x5A,0x89,0x9F,0xA5,)
  1934.       D(0xAE,0x9F,0x24,0x11,) D(0x7C,0x4B,0x1F,0xE6,) D(0x49,0x28,0x66,0x51,)
  1935.       D(0xEC,0xE4,0x5B,0x3D,) D(0xC2,0x00,0x7C,0xB8,) D(0xA1,0x63,0xBF,0x05,)
  1936.       D(0x98,0xDA,0x48,0x36,) D(0x1C,0x55,0xD3,0x9A,) D(0x69,0x16,0x3F,0xA8,)
  1937.       D(0xFD,0x24,0xCF,0x5F,) D(0x83,0x65,0x5D,0x23,) D(0xDC,0xA3,0xAD,0x96,)
  1938.       D(0x1C,0x62,0xF3,0x56,) D(0x20,0x85,0x52,0xBB,) D(0x9E,0xD5,0x29,0x07,)
  1939.       D(0x70,0x96,0x96,0x6D,) D(0x67,0x0C,0x35,0x4E,) D(0x4A,0xBC,0x98,0x04,)
  1940.       D(0xF1,0x74,0x6C,0x08,) D(0xCA,0x18,0x21,0x7C,) D(0x32,0x90,0x5E,0x46,)
  1941.       D(0x2E,0x36,0xCE,0x3B,) D(0xE3,0x9E,0x77,0x2C,) D(0x18,0x0E,0x86,0x03,)
  1942.       D(0x9B,0x27,0x83,0xA2,) D(0xEC,0x07,0xA2,0x8F,) D(0xB5,0xC5,0x5D,0xF0,)
  1943.       D(0x6F,0x4C,0x52,0xC9,) D(0xDE,0x2B,0xCB,0xF6,) D(0x95,0x58,0x17,0x18,)
  1944.       D(0x39,0x95,0x49,0x7C,) D(0xEA,0x95,0x6A,0xE5,) D(0x15,0xD2,0x26,0x18,)
  1945.       D(0x98,0xFA,0x05,0x10,) D(0x15,0x72,0x8E,0x5A,) D(0x8A,0xAA,0xC4,0x2D,)
  1946.       D(0xAD,0x33,0x17,0x0D,) D(0x04,0x50,0x7A,0x33,) D(0xA8,0x55,0x21,0xAB,)
  1947.       D(0xDF,0x1C,0xBA,0x65,) } ;
  1948.  
  1949. # Mantisse von ln(2) :
  1950.   local uintD ln2_mantisse [64/intDsize] =
  1951.     { D(0xB1,0x72,0x17,0xF7,) D(0xD1,0xCF,0x79,0xAC,) } ;
  1952.  
  1953. # Mantisse von ln(10) :
  1954.   local uintD ln10_mantisse [64/intDsize] =
  1955.     { D(0x93,0x5D,0x8D,0xDD,) D(0xAA,0xA8,0xAC,0x17,) } ;
  1956.  
  1957. # UP: Initialisiert die Arithmetik.
  1958. # init_arith();
  1959. # kann GC ausl÷sen
  1960.   global void init_arith (void);
  1961.   global void init_arith()
  1962.     { # verschiedene konstante Zahlen:
  1963.       #ifndef WIDE
  1964.       O(FF_zero) = allocate_ffloat(0); # 0.0F0
  1965.       # encode_FF(0,1,bit(FF_mant_len), O(FF_one)=); # 1.0F0
  1966.       # encode_FF(-1,1,bit(FF_mant_len), O(FF_minusone)=); # -1.0F0
  1967.       #endif
  1968.       #ifdef intQsize
  1969.       O(DF_zero) = allocate_dfloat(0); # 0.0D0
  1970.       # encode_DF(0,1,bit(DF_mant_len), O(DF_one)=); # 1.0D0
  1971.       # encode_DF(-1,1,bit(DF_mant_len), O(DF_minusone)=); # -1.0D0
  1972.       #else
  1973.       O(DF_zero) = allocate_dfloat(0,0); # 0.0D0
  1974.       # encode2_DF(0,1,bit(DF_mant_len-32),0, O(DF_one)=); # 1.0D0
  1975.       # encode2_DF(-1,1,bit(DF_mant_len-32),0, O(DF_minusone)=); # -1.0D0
  1976.       #endif
  1977.       # variable Long-Floats:
  1978.       encode_LF(0,2,&pi_mantisse[0],2048/intDsize, O(LF_pi)=); # pi auf 2048 Bits
  1979.       encode_LF(0,0,&ln2_mantisse[0],64/intDsize, O(LF_ln2)=); # ln(2) auf 64 Bits
  1980.       encode_LF(0,2,&ln10_mantisse[0],64/intDsize, O(LF_ln10)=); # ln(10) auf 64 Bits
  1981.       # DefaultlΣnge von Long-Floats so klein wie m÷glich:
  1982.       set_lf_digits(LF_minlen);
  1983.       # pi als Short-, Single-, Double-Float:
  1984.       O(SF_pi) = LF_to_SF(O(pi));
  1985.       O(FF_pi) = LF_to_FF(O(pi));
  1986.       O(DF_pi) = LF_to_DF(O(pi));
  1987.       # MOST-POSITIVE-FIXNUM, MOST-NEGATIVE-FIXNUM :
  1988.       define_constant(S(most_positive_fixnum),Fixnum_mpos);
  1989.       define_constant(S(most_negative_fixnum),Fixnum_mneg);
  1990.       # MOST/LEAST-POSITIVE/NEGATIVE-SHORT-FLOAT:
  1991.       define_constant(S(most_positive_short_float),make_SF(0,SF_exp_high,bit(SF_mant_len+1)-1));
  1992.       define_constant(S(least_positive_short_float),make_SF(0,SF_exp_low,bit(SF_mant_len)));
  1993.       define_constant(S(least_negative_short_float),make_SF(-1,SF_exp_low,bit(SF_mant_len)));
  1994.       define_constant(S(most_negative_short_float),make_SF(-1,SF_exp_high,bit(SF_mant_len+1)-1));
  1995.       # MOST/LEAST-POSITIVE/NEGATIVE-SINGLE-FLOAT:
  1996.       {var reg1 object obj; encode_FF(0,FF_exp_high-FF_exp_mid,bit(FF_mant_len+1)-1, obj=);
  1997.        define_constant(S(most_positive_single_float),obj); }
  1998.       {var reg1 object obj; encode_FF(0,FF_exp_low-FF_exp_mid,bit(FF_mant_len), obj=);
  1999.        define_constant(S(least_positive_single_float),obj); }
  2000.       {var reg1 object obj; encode_FF(-1,FF_exp_low-FF_exp_mid,bit(FF_mant_len), obj=);
  2001.        define_constant(S(least_negative_single_float),obj); }
  2002.       {var reg1 object obj; encode_FF(-1,FF_exp_high-FF_exp_mid,bit(FF_mant_len+1)-1, obj=);
  2003.        define_constant(S(most_negative_single_float),obj); }
  2004.       # MOST/LEAST-POSITIVE/NEGATIVE-DOUBLE-FLOAT:
  2005.       {var reg1 object obj;
  2006.        #ifdef intQsize
  2007.        encode_DF(0,DF_exp_high-DF_exp_mid,bit(DF_mant_len+1)-1, obj=);
  2008.        #else
  2009.        encode2_DF(0,DF_exp_high-DF_exp_mid,bit(DF_mant_len-32+1)-1,bitm(32)-1, obj=);
  2010.        #endif
  2011.        define_constant(S(most_positive_double_float),obj); }
  2012.       {var reg1 object obj;
  2013.        #ifdef intQsize
  2014.        encode_DF(0,DF_exp_low-DF_exp_mid,bit(DF_mant_len), obj=);
  2015.        #else
  2016.        encode2_DF(0,DF_exp_low-DF_exp_mid,bit(DF_mant_len-32),0, obj=);
  2017.        #endif
  2018.        define_constant(S(least_positive_double_float),obj); }
  2019.       {var reg1 object obj;
  2020.        #ifdef intQsize
  2021.        encode_DF(-1,DF_exp_low-DF_exp_mid,bit(DF_mant_len), obj=);
  2022.        #else
  2023.        encode2_DF(-1,DF_exp_low-DF_exp_mid,bit(DF_mant_len-32),0, obj=);
  2024.        #endif
  2025.        define_constant(S(least_negative_double_float),obj); }
  2026.       {var reg1 object obj;
  2027.        #ifdef intQsize
  2028.        encode_DF(-1,DF_exp_high-DF_exp_mid,bit(DF_mant_len+1)-1, obj=);
  2029.        #else
  2030.        encode2_DF(-1,DF_exp_high-DF_exp_mid,bit(DF_mant_len-32+1)-1,bitm(32)-1, obj=);
  2031.        #endif
  2032.        define_constant(S(most_negative_double_float),obj); }
  2033.       # Bei Floats mit d Bits (incl. Hiddem Bit, also d = ?F_mant_len+1)
  2034.       # ist ...-FLOAT-EPSILON = 2^-d*(1+2^(1-d))
  2035.       # und ...-FLOAT-NEGATIVE-EPSILON = 2^(-d-1)*(1+2^(1-d)) .
  2036.       define_constant(S(short_float_epsilon),make_SF(0,SF_exp_mid-SF_mant_len,bit(SF_mant_len)+1));
  2037.       define_constant(S(short_float_negative_epsilon),make_SF(0,SF_exp_mid-SF_mant_len-1,bit(SF_mant_len)+1));
  2038.       {var reg1 object obj; encode_FF(0,-FF_mant_len,bit(FF_mant_len)+1, obj=);
  2039.        define_constant(S(single_float_epsilon),obj); }
  2040.       {var reg1 object obj; encode_FF(0,-FF_mant_len-1,bit(FF_mant_len)+1, obj=);
  2041.        define_constant(S(single_float_negative_epsilon),obj); }
  2042.       {var reg1 object obj;
  2043.        #ifdef intQsize
  2044.        encode_DF(0,-DF_mant_len,bit(DF_mant_len)+1, obj=);
  2045.        #else
  2046.        encode2_DF(0,-DF_mant_len,bit(DF_mant_len-32),1, obj=);
  2047.        #endif
  2048.        define_constant(S(double_float_epsilon),obj); }
  2049.       {var reg1 object obj;
  2050.        #ifdef intQsize
  2051.        encode_DF(0,-DF_mant_len-1,bit(DF_mant_len)+1, obj=);
  2052.        #else
  2053.        encode2_DF(0,-DF_mant_len-1,bit(DF_mant_len-32),1, obj=);
  2054.        #endif
  2055.        define_constant(S(double_float_negative_epsilon),obj); }
  2056.       # weitere Variablen:
  2057.       define_variable(S(default_float_format),S(single_float)); # *DEFAULT-FLOAT-FORMAT* := 'SINGLE-FLOAT
  2058.       define_variable(S(read_default_float_format),S(single_float)); # *READ-DEFAULT-FLOAT-FORMAT* := 'SINGLE-FLOAT
  2059.       {var reg1 object obj = make_random_state(T); # neuer zufΣlliger Random-State
  2060.        define_variable(S(random_state_stern),obj); } # =: *RANDOM-STATE*
  2061.     }
  2062.  
  2063.