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

  1. # Addition/Subtraktion von Integers
  2.  
  3. # Macro: In der DS MSDptr/len/LSDptr wird eine 1 unterhalb des Pointers ptr
  4. # addiert. Unterhalb von MSDptr muß 1 Digit Platz sein.
  5. # Dabei ist  ptr - MSDptr = count  und  0 < count <= len .
  6. # Eventuell wird MSDptr erniedrigt und len erhöht.
  7.   #define DS_1_plus(ptr,count)  \
  8.     {var reg1 uintD* ptr_from_DS_1_plus = (ptr);                    \
  9.      var reg2 uintC count_from_DS_1_plus = (count);                 \
  10.      loop { if (--count_from_DS_1_plus==0) # Zähler erniedrigen     \
  11.               { # Beim Most Significant Digit angelangt             \
  12.                 *(--ptr_from_DS_1_plus) += 1;                       \
  13.                 # jetzt ist ptr_from_DS_1_plus = MSDptr             \
  14.                 if (*ptr_from_DS_1_plus == bit(intDsize-1))         \
  15.                   { # 7FFF + 1 muß zu 00008000 werden:              \
  16.                     *--MSDptr = 0;                                  \
  17.                     len++; if (uintCoverflow(len)) BN_ueberlauf();  \
  18.                   }                                                 \
  19.                 break;                                              \
  20.               }                                                     \
  21.             if (!((*(--ptr_from_DS_1_plus) += 1) == 0)) # weiterincrementieren \
  22.               break; # kein weiterer Übertrag -> Schleife abbrechen \
  23.     }     }
  24.  
  25. # Macro: In der DS MSDptr/len/LSDptr wird eine 1 unterhalb des Pointers ptr
  26. # subtrahiert. Unterhalb von MSDptr muß 1 Digit Platz sein.
  27. # Dabei ist  ptr - MSDptr = count  und  0 < count <= len .
  28. # Eventuell wird MSDptr erniedrigt und len erhöht.
  29.   #define DS_minus1_plus(ptr,count)  \
  30.     {var reg1 uintD* ptr_from_DS_minus1_plus = (ptr);                \
  31.      var reg2 uintC count_from_DS_minus1_plus = (count);             \
  32.      loop { if (--count_from_DS_minus1_plus==0) # Zähler erniedrigen \
  33.               { # Beim Most Significant Digit angelangt              \
  34.                 *(--ptr_from_DS_minus1_plus) -= 1;                   \
  35.                 # jetzt ist ptr_from_DS_minus1_plus = MSDptr         \
  36.                 if (*ptr_from_DS_minus1_plus == (uintD)bit(intDsize-1)-1) \
  37.                   { # 8000 - 1 muß zu FFFF7FFF werden:               \
  38.                     *--MSDptr = -1;                                  \
  39.                     len++; if (uintCoverflow(len)) BN_ueberlauf();   \
  40.                   }                                                  \
  41.                 break;                                               \
  42.               }                                                      \
  43.             if (!((sintD)(*(--ptr_from_DS_minus1_plus) -= 1) == -1)) # weiterdecrementieren \
  44.               break; # kein weiterer Übertrag -> Schleife abbrechen  \
  45.     }     }
  46.  
  47. # (1+ x), wo x ein Integer ist. Ergebnis Integer.
  48. # kann GC auslösen
  49.   global object I_1_plus_I (object x);
  50.   global object I_1_plus_I(x)
  51.     var reg3 object x;
  52.     { if (I_fixnump(x))
  53.         { # x ist Fixnum
  54.           if (eq(x,Fixnum_minus1)) { return Fixnum_0; } # (1+ -1) = 0
  55.           if (!eq(x,Fixnum_mpos)) { return fixnum_inc(x,1); } # bleibt Fixnum: direkt 1 addieren
  56.         }
  57.       # die sichere Methode
  58.       { SAVE_NUM_STACK # num_stack retten
  59.         var uintD* MSDptr;
  60.         var uintC len;
  61.         var uintD* LSDptr;
  62.         I_to_NDS_1(x, MSDptr=,len=,LSDptr=); # NDS zu x bilden.
  63.         DS_1_plus(LSDptr,len); # zur NDS 1 addieren
  64.         RESTORE_NUM_STACK # num_stack (vorzeitig) zurück
  65.         return DS_to_I(MSDptr,len); # wieder zum Integer machen
  66.     } }
  67.  
  68. # (1- x), wo x ein Integer ist. Ergebnis Integer.
  69. # kann GC auslösen
  70.   global object I_minus1_plus_I (object x);
  71.   global object I_minus1_plus_I(x)
  72.     var reg3 object x;
  73.     { if (I_fixnump(x))
  74.         { # x ist Fixnum
  75.           if (eq(x,Fixnum_0)) { return Fixnum_minus1; } # (1- 0) = -1
  76.           if (!eq(x,Fixnum_mneg)) { return fixnum_inc(x,-1); } # bleibt Fixnum: direkt 1 subtrahieren
  77.         }
  78.       # die sichere Methode
  79.       { SAVE_NUM_STACK # num_stack retten
  80.         var uintD* MSDptr;
  81.         var uintC len;
  82.         var uintD* LSDptr;
  83.         I_to_NDS_1(x, MSDptr=,len=,LSDptr=); # NDS zu x bilden.
  84.         DS_minus1_plus(LSDptr,len); # von der NDS 1 subtrahieren
  85.         RESTORE_NUM_STACK # num_stack (vorzeitig) zurück
  86.         return DS_to_I(MSDptr,len); # wieder zum Integer machen
  87.     } }
  88.  
  89. # (+ x y), wo x und y Integers sind. Ergebnis Integer.
  90. # kann GC auslösen
  91.   global object I_I_plus_I (object x, object y);
  92.   global object I_I_plus_I(x,y)
  93.     var reg3 object x;
  94.     var reg3 object y;
  95.     # Methode:
  96.     # x Fixnum ->
  97.     #   y Fixnum -> beide direkt addieren, mit L_to_I beenden
  98.     #   y Bignum -> falls x=0, y; sonst beide zu DS machen, addieren.
  99.     # x Bignum ->
  100.     #   y Fixnum -> falls y=0, x; sonst beide zu DS machen, addieren.
  101.     #   y Bignum -> beide zu DS machen, addieren.
  102.     { var reg4 uintD* MSDptr;
  103.       var reg4 uintC len;
  104.       var reg4 uintD* LSDptr;
  105.       # MSDptr/len/LSDptr bilden die DS des Ergebnisses.
  106.       if (I_fixnump(x))
  107.         { # x ist Fixnum
  108.           if (I_fixnump(y))
  109.             { # x,y sind Fixnums
  110.               #if (oint_data_len+1 < intLsize)
  111.               return L_to_I( FN_to_L(x) + FN_to_L(y) ); # als 32-Bit-Zahlen addieren
  112.               #elif defined(intQsize)
  113.               return Q_to_I( FN_to_Q(x) + FN_to_Q(y) ); # als 64-Bit-Zahlen addieren
  114.               #else
  115.               var reg2 sint32 xhi = R_sign(x);
  116.               var reg1 uint32 xlo = FN_to_L(x);
  117.               var reg5 sint32 yhi = R_sign(y);
  118.               var reg4 uint32 ylo = FN_to_L(y);
  119.               xhi += yhi;
  120.               xlo += ylo;
  121.               if (xlo < ylo) { xhi += 1; }
  122.               return L2_to_I(xhi,xlo);
  123.               #endif
  124.             }
  125.             else
  126.             { # x ist Fixnum, y ist Bignum
  127.              {var reg1 object h; h = x; x = y; y = h; } # x und y vertauschen
  128.              goto xBN_yFN;
  129.             }
  130.         }
  131.         else
  132.         { # x ist Bignum
  133.           if (I_fixnump(y))
  134.             xBN_yFN:
  135.             { # x ist Bignum, y ist Fixnum, also x länger
  136.               var reg2 sint32 y_ = FN_to_L(y); # Wert von y
  137.               if (FN_L_zerop(y,y_)) { return x; } # bei y=0 Ergebnis x
  138.              {SAVE_NUM_STACK # num_stack retten
  139.               BN_to_NDS_1(x, MSDptr=,len=,LSDptr=); # NDS zu x bilden.
  140.               # len>=bn_minlength. len>pFN_maxlength erzwingen:
  141.               if ((bn_minlength==pFN_maxlength) && (len==pFN_maxlength))
  142.                 { var reg1 sintD sign = sign_of_sintD(MSDptr[0]);
  143.                   *--MSDptr = sign; len++;
  144.                 }
  145.               # y_ zu den oberen pFN_maxlength Digits von x addieren:
  146.               { var reg2 uintD* midptr = &LSDptr[-(uintP)pFN_maxlength];
  147.                 var reg1 uint32 x_ = pFN_maxlength_digits_at(midptr);
  148.                 var reg1 uint32 x_new = x_+(uint32)y_;
  149.                 set_pFN_maxlength_digits_at(midptr,x_new);
  150.                 if (x_new < x_)
  151.                   { # Carry.
  152.                     if (!FN_L_minusp(y,y_)) # kürzerer Summand war positiv
  153.                       # Dann ist ein positiver Übertrag weiterzutragen
  154.                       # (Beispiel: 0002FFFC + 0007 = 00030003)
  155.                       { DS_1_plus(midptr,len-pFN_maxlength); }
  156.                   }
  157.                   else
  158.                   { # Kein Carry.
  159.                     if (FN_L_minusp(y,y_)) # kürzerer Summand war negativ
  160.                       # Dann ist ein negativer Übertrag weiterzutragen
  161.                       # (Beispiel: 00020003 + FFF5 = 0001FFF8)
  162.                       { DS_minus1_plus(midptr,len-pFN_maxlength); }
  163.               }   }
  164.               RESTORE_NUM_STACK # num_stack (vorzeitig) zurück
  165.               return DS_to_I(MSDptr,len); # DS wieder zum Integer machen
  166.             }}
  167.             else
  168.             { # x und y sind Bignums
  169.               SAVE_NUM_STACK # num_stack retten
  170.               if (TheBignum(x)->length < TheBignum(y)->length)
  171.                 {var reg1 object h; h = x; x = y; y = h; } # x und y vertauschen
  172.               # Nun ist x das längere von beiden.
  173.               BN_to_NDS_1(x, MSDptr=,len=,LSDptr=); # NDS zu x bilden.
  174.              {var reg4 uintD* yMSDptr;
  175.               var reg2 uintC ylen;
  176.               var reg1 uintD* yLSDptr;
  177.               BN_to_NDS_nocopy(y, yMSDptr=,ylen=,yLSDptr=); # NDS zu y bilden.
  178.               # yMSDptr/ylen/yLSDptr bilden die DS des kürzeren Arguments y.
  179.               # len>ylen erzwingen:
  180.               if (len==ylen)
  181.                 { var reg1 sintD sign = sign_of_sintD(MSDptr[0]);
  182.                   *--MSDptr = sign; len++; if (uintCoverflow(len)) BN_ueberlauf();
  183.                 }
  184.               # addieren:
  185.               { var reg4 uintD* midptr = LSDptr-(uintP)ylen;
  186.                 var reg5 uintD carry = addto_loop_down(yLSDptr,LSDptr,ylen);
  187.                 if (carry)
  188.                   { # Carry.
  189.                     if ((sintD)yMSDptr[0] >=0) # kürzerer Summand war positiv
  190.                       # Dann ist ein positiver Übertrag weiterzutragen
  191.                       # (Beispiel: 0002FFFC + 0007 = 00030003)
  192.                       { DS_1_plus(midptr,len-ylen); }
  193.                   }
  194.                   else
  195.                   { # Kein Carry.
  196.                     if ((sintD)yMSDptr[0] <0) # kürzerer Summand war negativ
  197.                       # Dann ist ein negativer Übertrag weiterzutragen
  198.                       # (Beispiel: 00020003 + FFF5 = 0001FFF8)
  199.                       { DS_minus1_plus(midptr,len-ylen); }
  200.               }   }
  201.               RESTORE_NUM_STACK # num_stack (vorzeitig) zurück
  202.               return DS_to_I(MSDptr,len); # DS wieder zum Integer machen
  203.             }}
  204.     }   }
  205.  
  206. # (- x), wenn x ein Integer ist. Ergebnis Integer.
  207. # kann GC auslösen
  208.   local object I_minus_I (object x);
  209.   local object I_minus_I(x)
  210.     var reg2 object x;
  211.     { if (I_fixnump(x))
  212.         { # Fixnum -> Long, negieren, -> Integer
  213.           #if (oint_data_len+1 < intLsize)
  214.           return L_to_I(- FN_to_L(x));
  215.           #elif defined(intQsize)
  216.           return Q_to_I(- FN_to_Q(x));
  217.           #else
  218.           var reg3 sint32 xhi = R_sign(x);
  219.           var reg1 uint32 xlo = FN_to_L(x);
  220.           if (xlo==0) { xhi = -xhi; } else { xlo = -xlo; xhi = ~xhi; }
  221.           return L2_to_I(xhi,xlo);
  222.           #endif
  223.         }
  224.         else
  225.         { # x Bignum
  226.           SAVE_NUM_STACK # num_stack retten
  227.           var reg4 uintD* MSDptr;
  228.           var reg4 uintC len;
  229.           var reg4 uintD* LSDptr;
  230.           BN_to_NDS_1(x, MSDptr=,len=,LSDptr=); # NDS zu x bilden, len>0
  231.           # vorsorglich 1 Digit mehr belegen:
  232.           { var reg1 sintD sign = sign_of_sintD(MSDptr[0]);
  233.             *--MSDptr = sign; len++; if (uintCoverflow(len)) BN_ueberlauf();
  234.           }
  235.           # Negierschleife:
  236.           neg_loop_down(LSDptr,len);
  237.           # MSDigit ist nun = 0x0000 oder = 0xFFFF
  238.           RESTORE_NUM_STACK # num_stack (vorzeitig) zurück
  239.           return DS_to_I(MSDptr,len); # DS wieder zum Integer machen
  240.     }   }
  241.  
  242. # (- x y), wo x und y Integers sind. Ergebnis Integer.
  243. # kann GC auslösen
  244.   global object I_I_minus_I (object x, object y);
  245.   global object I_I_minus_I(x,y)
  246.     var reg3 object x;
  247.     var reg3 object y;
  248.     # Methode:
  249.     # x Fixnum ->
  250.     #   y Fixnum -> beide direkt subtrahieren, mit L_to_I beenden
  251.     #   y Bignum -> falls x=0, (- y); sonst beide zu DS machen, subtrahieren.
  252.     # x Bignum ->
  253.     #   y Fixnum -> falls y=0, x; sonst beide zu DS machen, subtrahieren.
  254.     #   y Bignum -> beide zu DS machen, subtrahieren.
  255.     { var reg4 uintD* MSDptr;
  256.       var reg4 uintC len;
  257.       var reg4 uintD* LSDptr;
  258.       # MSDptr/len/LSDptr bilden die DS des Ergebnisses.
  259.       if (I_fixnump(x))
  260.         { # x ist Fixnum
  261.           if (I_fixnump(y))
  262.             { # x,y sind Fixnums
  263.               #if (oint_data_len+1 < intLsize)
  264.               return L_to_I( FN_to_L(x) - FN_to_L(y) ); # als 32-Bit-Zahlen subtrahieren
  265.               #elif defined(intQsize)
  266.               return Q_to_I( FN_to_Q(x) - FN_to_Q(y) ); # als 64-Bit-Zahlen subtrahieren
  267.               #else
  268.               var reg2 sint32 xhi = R_sign(x);
  269.               var reg1 uint32 xlo = FN_to_L(x);
  270.               var reg5 sint32 yhi = R_sign(y);
  271.               var reg4 uint32 ylo = FN_to_L(y);
  272.               xhi -= yhi;
  273.               if (xlo < ylo) { xhi -= 1; }
  274.               xlo -= ylo;
  275.               return L2_to_I(xhi,xlo);
  276.               #endif
  277.             }
  278.             else
  279.             { # x ist Fixnum, y ist Bignum, also y länger
  280.               var reg2 sint32 x_ = FN_to_L(x); # Wert von x
  281.               if (FN_L_zerop(x,x_)) { return I_minus_I(y); } # bei x=0 Ergebnis (- y)
  282.              {SAVE_NUM_STACK # num_stack retten
  283.               BN_to_NDS_1(y, MSDptr=,len=,LSDptr=); # NDS zu y bilden.
  284.               # vorsorglich 1 Digit mehr belegen:
  285.               { var reg1 sintD sign = sign_of_sintD(MSDptr[0]);
  286.                 *--MSDptr = sign; len++; if (uintCoverflow(len)) BN_ueberlauf();
  287.               }
  288.               # Negierschleife:
  289.               neg_loop_down(LSDptr,len);
  290.               # MSDigit ist nun = 0x0000 oder = 0xFFFF
  291.               # x_ zu den oberen pFN_maxlength Digits von -y addieren:
  292.               { var reg2 uintD* midptr = &LSDptr[-(uintP)pFN_maxlength];
  293.                 var reg1 uint32 y_ = pFN_maxlength_digits_at(midptr);
  294.                 var reg1 uint32 y_new = y_+(uint32)x_;
  295.                 set_pFN_maxlength_digits_at(midptr,y_new);
  296.                 if (y_new < y_)
  297.                   { # Carry.
  298.                     if (!FN_L_minusp(x,x_)) # kürzerer Summand war positiv
  299.                       # Dann ist ein positiver Übertrag weiterzutragen
  300.                       # (Beispiel: 0002FFFC + 0007 = 00030003)
  301.                       { DS_1_plus(midptr,len-pFN_maxlength); }
  302.                   }
  303.                   else
  304.                   { # Kein Carry.
  305.                     if (FN_L_minusp(x,x_)) # kürzerer Summand war negativ
  306.                       # Dann ist ein negativer Übertrag weiterzutragen
  307.                       # (Beispiel: 00020003 + FFF5 = 0001FFF8)
  308.                       { DS_minus1_plus(midptr,len-pFN_maxlength); }
  309.               }   }
  310.               RESTORE_NUM_STACK # num_stack (vorzeitig) zurück
  311.               return DS_to_I(MSDptr,len); # DS wieder zum Integer machen
  312.             }}
  313.         }
  314.         else
  315.         { # x ist Bignum
  316.           if (I_fixnump(y))
  317.             { # x ist Bignum, y ist Fixnum, also x länger
  318.               var reg2 sint32 y_ = FN_to_L(y); # Wert von y
  319.               if (FN_L_zerop(y,y_)) { return x; } # bei y=0 Ergebnis x
  320.              {SAVE_NUM_STACK # num_stack retten
  321.               BN_to_NDS_1(x, MSDptr=,len=,LSDptr=); # NDS zu x bilden.
  322.               # len>=bn_minlength. len>pFN_maxlength erzwingen:
  323.               if ((bn_minlength==pFN_maxlength) && (len==pFN_maxlength))
  324.                 { var reg1 sintD sign = sign_of_sintD(MSDptr[0]);
  325.                   *--MSDptr = sign; len++;
  326.                 }
  327.               # y_ von den oberen pFN_maxlength Digits von x subtrahieren:
  328.               { var reg2 uintD* midptr = &LSDptr[-(uintP)pFN_maxlength];
  329.                 var reg1 uint32 x_ = pFN_maxlength_digits_at(midptr);
  330.                 var reg1 uint32 x_new = x_-(uint32)y_;
  331.                 set_pFN_maxlength_digits_at(midptr,x_new);
  332.                 if (x_new > x_) # bzw. (x_ < (uint32)y_), da y_>0
  333.                   { # Carry.
  334.                     if (!FN_L_minusp(y,y_)) # kürzerer Summand war positiv
  335.                       # Dann ist ein negativer Übertrag weiterzutragen
  336.                       # (Beispiel: 00030003 - 0007 = 0002FFFC)
  337.                       { DS_minus1_plus(midptr,len-pFN_maxlength); }
  338.                   }
  339.                   else
  340.                   { # Kein Carry.
  341.                     if (FN_L_minusp(y,y_)) # kürzerer Summand war negativ
  342.                       # Dann ist ein positiver Übertrag weiterzutragen
  343.                       # (Beispiel: 0002FFF8 - FFF5 = 00030003)
  344.                       { DS_1_plus(midptr,len-pFN_maxlength); }
  345.               }   }
  346.               RESTORE_NUM_STACK # num_stack (vorzeitig) zurück
  347.               return DS_to_I(MSDptr,len); # DS wieder zum Integer machen
  348.             }}
  349.             else
  350.             { # x und y sind Bignums
  351.               if (TheBignum(x)->length > TheBignum(y)->length)
  352.                 { # x das längere von beiden.
  353.                   SAVE_NUM_STACK # num_stack retten
  354.                   BN_to_NDS_1(x, MSDptr=,len=,LSDptr=); # NDS zu x bilden.
  355.                  {var reg4 uintD* yMSDptr;
  356.                   var reg2 uintC ylen;
  357.                   var reg1 uintD* yLSDptr;
  358.                   BN_to_NDS_nocopy(y, yMSDptr=,ylen=,yLSDptr=); # NDS zu y bilden.
  359.                   # yMSDptr/ylen/yLSDptr bilden die DS des kürzeren Arguments y.
  360.                   # Es ist len>ylen.
  361.                   # subtrahieren:
  362.                   { var reg4 uintD* midptr = LSDptr-(uintP)ylen;
  363.                     var reg5 uintD carry = subfrom_loop_down(yLSDptr,LSDptr,ylen);
  364.                     if (carry)
  365.                       { # Carry.
  366.                         if ((sintD)yMSDptr[0] >=0) # kürzerer Summand war positiv
  367.                           # Dann ist ein negativer Übertrag weiterzutragen
  368.                           # (Beispiel: 00030003 - 0007 = 0002FFFC)
  369.                           { DS_minus1_plus(midptr,len-ylen); }
  370.                       }
  371.                       else
  372.                       { # Kein Carry.
  373.                         if ((sintD)yMSDptr[0] <0) # kürzerer Summand war negativ
  374.                           # Dann ist ein positiver Übertrag weiterzutragen
  375.                           # (Beispiel: 0002FFF8 - FFF5 = 00030003)
  376.                           { DS_1_plus(midptr,len-ylen); }
  377.                   }   }
  378.                   RESTORE_NUM_STACK # num_stack (vorzeitig) zurück
  379.                   return DS_to_I(MSDptr,len); # DS wieder zum Integer machen
  380.                 }}
  381.                 else
  382.                 { # y das längere von beiden.
  383.                   SAVE_NUM_STACK # num_stack retten
  384.                   BN_to_NDS_1(y, MSDptr=,len=,LSDptr=); # NDS zu y bilden.
  385.                   # vorsorglich 1 Digit mehr belegen:
  386.                   { var reg1 sintD sign = sign_of_sintD(MSDptr[0]);
  387.                     *--MSDptr = sign; len++; if (uintCoverflow(len)) BN_ueberlauf();
  388.                   }
  389.                   # Negierschleife:
  390.                   neg_loop_down(LSDptr,len);
  391.                   # MSDigit ist nun = 0x0000 oder = 0xFFFF
  392.                  {var reg4 uintD* xMSDptr;
  393.                   var reg2 uintC xlen;
  394.                   var reg1 uintD* xLSDptr;
  395.                   BN_to_NDS_nocopy(x, xMSDptr=,xlen=,xLSDptr=); # NDS zu x bilden.
  396.                   # xMSDptr/xlen/xLSDptr bilden die DS des kürzeren Arguments x.
  397.                   # Es ist jetzt len>xlen.
  398.                   # addieren:
  399.                   { var reg4 uintD* midptr = LSDptr-(uintP)xlen;
  400.                     var reg5 uintD carry = addto_loop_down(xLSDptr,LSDptr,xlen);
  401.                     if (carry)
  402.                       { # Carry.
  403.                         if ((sintD)xMSDptr[0] >=0) # kürzerer Summand war positiv
  404.                           # Dann ist ein positiver Übertrag weiterzutragen
  405.                           # (Beispiel: 0002FFFC + 0007 = 00030003)
  406.                           { DS_1_plus(midptr,len-xlen); }
  407.                       }
  408.                       else
  409.                       { # Kein Carry.
  410.                         if ((sintD)xMSDptr[0] <0) # kürzerer Summand war negativ
  411.                           # Dann ist ein negativer Übertrag weiterzutragen
  412.                           # (Beispiel: 00020003 + FFF5 = 0001FFF8)
  413.                           { DS_minus1_plus(midptr,len-xlen); }
  414.                   }   }
  415.                   RESTORE_NUM_STACK # num_stack (vorzeitig) zurück
  416.                   return DS_to_I(MSDptr,len); # DS wieder zum Integer machen
  417.                 }}
  418.     }   }   }
  419.  
  420. # (abs x), wenn x ein Integer ist. Ergebnis Integer.
  421. # kann GC auslösen
  422.   local object I_abs_I (object x);
  423.   local object I_abs_I(x)
  424.     var reg1 object x;
  425.     { # Methode:
  426.       # Bei x<0: (- x), sonst x.
  427.       if (R_minusp(x)) return I_minus_I(x); else return x;
  428.     }
  429.  
  430.