home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / CLISP-1.LHA / CLISP960530-sr.lha / src / lisparit.d < prev    next >
Encoding:
Text File  |  1996-04-15  |  73.4 KB  |  2,050 lines

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