LargeInteger.st
changeset 4828 796dcc9903cf
parent 4806 1b48e7420cfe
child 4831 98113bc11cdd
equal deleted inserted replaced
4827:905b98a07798 4828:796dcc9903cf
   911      For positive receivers, this is the same as #digitAt:;
   911      For positive receivers, this is the same as #digitAt:;
   912      for negative ones, the actual bit representation is returned."
   912      for negative ones, the actual bit representation is returned."
   913 
   913 
   914     |t digits|
   914     |t digits|
   915     sign < 0 ifFalse:[
   915     sign < 0 ifFalse:[
   916 	index > digitByteArray size ifTrue:[
   916         index > digitByteArray size ifTrue:[
   917 	    ^ 0
   917             ^ 0
   918 	].
   918         ].
   919 	^ digitByteArray at:index.
   919         ^ digitByteArray at:index.
   920     ].
   920     ].
   921     "/ negative int - do 2's complement here
   921     "/ negative int - do 2's complement here
   922 
   922 
   923     t := self bitInvert + 1.
   923     t := self bitInvert + 1.
   924     t sign:1.
   924     t sign:1.
   925     digits := t digits.
   925     digits := t digitBytes.
   926     index > digits size ifTrue:[
   926     index > digits size ifTrue:[
   927 	^ 16rFF
   927         ^ 16rFF
   928     ].
   928     ].
   929     ^ digits at:index.
   929     ^ digits at:index.
   930 
   930 
   931     "
   931     "
   932      16r11111111111111111111 negated digitByteAt:1
   932      16r11111111111111111111 negated digitByteAt:1
   933     "
   933     "
   934 
   934 
   935     "Created: / 25.10.1998 / 14:12:21 / cg"
   935     "Created: / 25.10.1998 / 14:12:21 / cg"
       
   936 !
       
   937 
       
   938 digitBytes
       
   939     "return a byteArray filled with the receivers bits
       
   940      (8 bits of the absolute value per element).
       
   941      Least significant byte is first!!"
       
   942 
       
   943     ^ digitByteArray
       
   944 
       
   945     "Modified: / 5.5.1999 / 14:57:03 / stefan"
       
   946 !
       
   947 
       
   948 digitBytesMSB:msbFlag
       
   949     "return a byteArray filled with the receivers bits
       
   950      (8 bits of the absolute value per element),
       
   951      if msbflag = true, most significant byte is first,
       
   952      otherwise least significant byte is first"
       
   953 
       
   954     msbFlag ifTrue:[
       
   955         ^ digitByteArray copyReverse.
       
   956     ].
       
   957     ^ digitByteArray
       
   958 
       
   959     "Modified: / 5.5.1999 / 14:57:03 / stefan"
   936 !
   960 !
   937 
   961 
   938 digitLength
   962 digitLength
   939     "return the number bytes used by this Integer.
   963     "return the number bytes used by this Integer.
   940      For negative receivers, the digitLength of its absolute value
   964      For negative receivers, the digitLength of its absolute value
   955 
   979 
   956     "Modified: 31.7.1997 / 13:18:28 / cg"
   980     "Modified: 31.7.1997 / 13:18:28 / cg"
   957 !
   981 !
   958 
   982 
   959 digits
   983 digits
   960     "return a byteArray filled with the receivers bits
   984     "obsolete,use #digitBytes"
   961      (8 bits of the absolute value per element)"
       
   962 
   985 
   963     ^ digitByteArray
   986     ^ digitByteArray
   964 
   987 
   965     "Modified: / 5.5.1999 / 14:57:03 / stefan"
   988     "Modified: / 5.5.1999 / 14:57:03 / stefan"
   966 ! !
   989 ! !
  1835     ] ifFalse:[
  1858     ] ifFalse:[
  1836         divisor := anInteger bitShift:shift.
  1859         divisor := anInteger bitShift:shift.
  1837     ].
  1860     ].
  1838 
  1861 
  1839     quo := self class basicNew numberOfDigits:((shift // 8) + 1). 
  1862     quo := self class basicNew numberOfDigits:((shift // 8) + 1). 
  1840     digits := quo digits.
  1863     digits := quo digitBytes.
  1841 
  1864 
  1842     shift := shift + 1.
  1865     shift := shift + 1.
  1843     [shift > 0] whileTrue:[
  1866     [shift > 0] whileTrue:[
  1844         (dividend absLess:divisor) ifFalse:[
  1867         (dividend absLess:divisor) ifFalse:[
  1845             digits bitSetAt:shift.
  1868             digits bitSetAt:shift.
  1872      d1   "{ Class: SmallInteger }"
  1895      d1   "{ Class: SmallInteger }"
  1873      d2   "{ Class: SmallInteger }"
  1896      d2   "{ Class: SmallInteger }"
  1874      otherDigitByteArray |
  1897      otherDigitByteArray |
  1875 
  1898 
  1876     len1 := digitByteArray size.
  1899     len1 := digitByteArray size.
  1877     otherDigitByteArray := aLargeInteger digits.
  1900     otherDigitByteArray := aLargeInteger digitBytes.
  1878     len2 := otherDigitByteArray size.
  1901     len2 := otherDigitByteArray size.
  1879 
  1902 
  1880     "/ the highest digit(s) should not be zero
  1903     "/ the highest digit(s) should not be zero
  1881     "/ when properly normalized; 
  1904     "/ when properly normalized; 
  1882     "/ but we are tolerant here, to allow for unnormalized
  1905     "/ but we are tolerant here, to allow for unnormalized
  1883     "/ numbers to be compared ...
  1906     "/ numbers to be compared ...
  1884 
  1907 
  1885     [(digitByteArray basicAt:len1) == 0] whileTrue:[
  1908     [(digitByteArray basicAt:len1) == 0] whileTrue:[
  1886 	len1 := len1 - 1
  1909         len1 := len1 - 1
  1887     ].
  1910     ].
  1888     [(otherDigitByteArray basicAt:len2) == 0] whileTrue:[
  1911     [(otherDigitByteArray basicAt:len2) == 0] whileTrue:[
  1889 	len2 := len2 - 1
  1912         len2 := len2 - 1
  1890     ].
  1913     ].
  1891     (len1 ~~ len2) ifTrue:[^ false].
  1914     (len1 ~~ len2) ifTrue:[^ false].
  1892     [len1 > 0] whileTrue:[
  1915     [len1 > 0] whileTrue:[
  1893 	d1 := digitByteArray basicAt:len1.
  1916         d1 := digitByteArray basicAt:len1.
  1894 	d2 := otherDigitByteArray basicAt:len1.
  1917         d2 := otherDigitByteArray basicAt:len1.
  1895 	(d1 ~~ d2) ifTrue:[^ false].
  1918         (d1 ~~ d2) ifTrue:[^ false].
  1896 	len1 := len1 - 1
  1919         len1 := len1 - 1
  1897     ].
  1920     ].
  1898     ^ true
  1921     ^ true
  1899 
  1922 
  1900     "Modified: / 8.5.1999 / 18:37:02 / cg"
  1923     "Modified: / 8.5.1999 / 18:37:02 / cg"
  1901 !
  1924 !
  1920         ^ Array with:0 with:self
  1943         ^ Array with:0 with:self
  1921     ].
  1944     ].
  1922 "
  1945 "
  1923     count := digitByteArray size.
  1946     count := digitByteArray size.
  1924     result := self class basicNew numberOfDigits:count.
  1947     result := self class basicNew numberOfDigits:count.
  1925     newDigitByteArray := result digits.
  1948     newDigitByteArray := result digitBytes.
  1926     ok := false.
  1949     ok := false.
  1927 %{
  1950 %{
  1928     OBJ __digits;
  1951     OBJ __digits;
  1929 
  1952 
  1930     __digits = __INST(digitByteArray);
  1953     __digits = __INST(digitByteArray);
  2042     len := digitByteArray size.
  2065     len := digitByteArray size.
  2043 
  2066 
  2044     rsltLen := len "+ 1".
  2067     rsltLen := len "+ 1".
  2045     result := self class basicNew numberOfDigits:rsltLen.
  2068     result := self class basicNew numberOfDigits:rsltLen.
  2046     result sign:newSign.
  2069     result sign:newSign.
  2047     resultDigitByteArray := result digits.
  2070     resultDigitByteArray := result digitBytes.
  2048 
  2071 
  2049     borrow := aSmallInteger abs.
  2072     borrow := aSmallInteger abs.
  2050 
  2073 
  2051 %{
  2074 %{
  2052     if (__isByteArray(__INST(digitByteArray))
  2075     if (__isByteArray(__INST(digitByteArray))
  2208         rsltLen := len + 1.
  2231         rsltLen := len + 1.
  2209     ].
  2232     ].
  2210 
  2233 
  2211     result := self class basicNew numberOfDigits:rsltLen.
  2234     result := self class basicNew numberOfDigits:rsltLen.
  2212     result sign:newSign.
  2235     result sign:newSign.
  2213     resultDigitByteArray := result digits.
  2236     resultDigitByteArray := result digitBytes.
  2214 
  2237 
  2215 %{
  2238 %{
  2216     if (__isByteArray(__INST(digitByteArray))
  2239     if (__isByteArray(__INST(digitByteArray))
  2217      && __isByteArray(resultDigitByteArray)
  2240      && __isByteArray(resultDigitByteArray)
  2218      && __isSmallInteger(aSmallInteger)) {
  2241      && __isSmallInteger(aSmallInteger)) {
  2298             unsigned char *__srcLastX;
  2321             unsigned char *__srcLastX;
  2299 
  2322 
  2300             __srcLastX = __srcLast - 3 - 4;
  2323             __srcLastX = __srcLast - 3 - 4;
  2301             while (__src <= __srcLastX) {
  2324             while (__src <= __srcLastX) {
  2302                 unsigned int __sum, __sum2;
  2325                 unsigned int __sum, __sum2;
  2303 		unsigned __digit1, __digit2;
  2326                 unsigned __digit1, __digit2;
  2304 
  2327 
  2305                 __digit1 = ((unsigned *)__src)[0];
  2328                 __digit1 = ((unsigned *)__src)[0];
  2306                 __digit2 = ((unsigned *)__src)[1];
  2329                 __digit2 = ((unsigned *)__src)[1];
  2307                 asm ("addl %%edx,%%ecx
  2330                 asm ("addl %%edx,%%ecx
  2308                       adcl $0, %%eax
  2331                       adcl $0, %%eax
  2533      d1   "{ Class: SmallInteger }"
  2556      d1   "{ Class: SmallInteger }"
  2534      d2   "{ Class: SmallInteger }"
  2557      d2   "{ Class: SmallInteger }"
  2535      otherDigitByteArray |
  2558      otherDigitByteArray |
  2536 
  2559 
  2537     myLen := digitByteArray size.
  2560     myLen := digitByteArray size.
  2538     otherDigitByteArray := aLargeInteger digits.
  2561     otherDigitByteArray := aLargeInteger digitBytes.
  2539     otherLen := otherDigitByteArray size.
  2562     otherLen := otherDigitByteArray size.
  2540 
  2563 
  2541     "/ the highest digit(s) should not be zero
  2564     "/ the highest digit(s) should not be zero
  2542     "/ when properly normalized; 
  2565     "/ when properly normalized; 
  2543     "/ but we are tolerant here, to allow for unnormalized
  2566     "/ but we are tolerant here, to allow for unnormalized
  2544     "/ numbers to be compared ...
  2567     "/ numbers to be compared ...
  2545 
  2568 
  2546     [myLen > 0 and:[(digitByteArray basicAt:myLen) == 0]] whileTrue:[
  2569     [myLen > 0 and:[(digitByteArray basicAt:myLen) == 0]] whileTrue:[
  2547 	myLen := myLen - 1
  2570         myLen := myLen - 1
  2548     ].
  2571     ].
  2549     [otherLen > 0 and:[(otherDigitByteArray basicAt:otherLen) == 0]] whileTrue:[
  2572     [otherLen > 0 and:[(otherDigitByteArray basicAt:otherLen) == 0]] whileTrue:[
  2550 	otherLen := otherLen - 1
  2573         otherLen := otherLen - 1
  2551     ].
  2574     ].
  2552     (myLen < otherLen) ifTrue:[^ true].
  2575     (myLen < otherLen) ifTrue:[^ true].
  2553     (myLen > otherLen) ifTrue:[^ false].
  2576     (myLen > otherLen) ifTrue:[^ false].
  2554 
  2577 
  2555     [myLen > 0] whileTrue:[
  2578     [myLen > 0] whileTrue:[
  2556 	d1 := digitByteArray basicAt:myLen.
  2579         d1 := digitByteArray basicAt:myLen.
  2557 	d2 := otherDigitByteArray basicAt:myLen.
  2580         d2 := otherDigitByteArray basicAt:myLen.
  2558 	d1 == d2 ifFalse:[
  2581         d1 == d2 ifFalse:[
  2559 	    (d1 < d2) ifTrue:[^ true].
  2582             (d1 < d2) ifTrue:[^ true].
  2560 	    ^ false
  2583             ^ false
  2561 	].
  2584         ].
  2562 	myLen := myLen - 1
  2585         myLen := myLen - 1
  2563     ].
  2586     ].
  2564     ^ false
  2587     ^ false
  2565 
  2588 
  2566     "Modified: / 3.5.1999 / 08:06:28 / stefan"
  2589     "Modified: / 3.5.1999 / 08:06:28 / stefan"
  2567     "Modified: / 8.5.1999 / 18:37:11 / cg"
  2590     "Modified: / 8.5.1999 / 18:37:11 / cg"
  2576      d1   "{ Class: SmallInteger }"
  2599      d1   "{ Class: SmallInteger }"
  2577      d2   "{ Class: SmallInteger }"
  2600      d2   "{ Class: SmallInteger }"
  2578      otherDigitByteArray |
  2601      otherDigitByteArray |
  2579 
  2602 
  2580     myLen := digitByteArray size.
  2603     myLen := digitByteArray size.
  2581     otherDigitByteArray := aLargeInteger digits.
  2604     otherDigitByteArray := aLargeInteger digitBytes.
  2582     otherLen := otherDigitByteArray size.
  2605     otherLen := otherDigitByteArray size.
  2583 
  2606 
  2584     "/ the highest digit(s) should not be zero
  2607     "/ the highest digit(s) should not be zero
  2585     "/ when properly normalized; 
  2608     "/ when properly normalized; 
  2586     "/ but we are tolerant here, to allow for unnormalized
  2609     "/ but we are tolerant here, to allow for unnormalized
  2587     "/ numbers to be compared ...
  2610     "/ numbers to be compared ...
  2588 
  2611 
  2589     [(digitByteArray basicAt:myLen) == 0] whileTrue:[
  2612     [(digitByteArray basicAt:myLen) == 0] whileTrue:[
  2590 	myLen := myLen - 1
  2613         myLen := myLen - 1
  2591     ].
  2614     ].
  2592     [(otherDigitByteArray basicAt:otherLen) == 0] whileTrue:[
  2615     [(otherDigitByteArray basicAt:otherLen) == 0] whileTrue:[
  2593 	otherLen := otherLen - 1
  2616         otherLen := otherLen - 1
  2594     ].
  2617     ].
  2595     (myLen < otherLen) ifTrue:[^ true].
  2618     (myLen < otherLen) ifTrue:[^ true].
  2596     (myLen > otherLen) ifTrue:[^ false].
  2619     (myLen > otherLen) ifTrue:[^ false].
  2597 
  2620 
  2598     [myLen > 0] whileTrue:[
  2621     [myLen > 0] whileTrue:[
  2599 	d1 := digitByteArray basicAt:myLen.
  2622         d1 := digitByteArray basicAt:myLen.
  2600 	d2 := otherDigitByteArray basicAt:myLen.
  2623         d2 := otherDigitByteArray basicAt:myLen.
  2601 	d1 == d2 ifFalse:[
  2624         d1 == d2 ifFalse:[
  2602 	    (d1 < d2) ifTrue:[^ true].
  2625             (d1 < d2) ifTrue:[^ true].
  2603 	    ^ false.
  2626             ^ false.
  2604 	].
  2627         ].
  2605 	myLen := myLen - 1
  2628         myLen := myLen - 1
  2606     ].
  2629     ].
  2607     ^ true
  2630     ^ true
  2608 
  2631 
  2609     "Created: / 13.2.1998 / 12:19:45 / stefan"
  2632     "Created: / 13.2.1998 / 12:19:45 / stefan"
  2610     "Modified: / 30.4.1999 / 12:46:31 / stefan"
  2633     "Modified: / 30.4.1999 / 12:46:31 / stefan"
  2628      carry  "{ Class: SmallInteger }" 
  2651      carry  "{ Class: SmallInteger }" 
  2629      lastDigit   
  2652      lastDigit   
  2630      lResult ok|
  2653      lResult ok|
  2631 
  2654 
  2632     len1 := digitByteArray size.
  2655     len1 := digitByteArray size.
  2633     otherDigitByteArray := aLargeInteger digits.
  2656     otherDigitByteArray := aLargeInteger digitBytes.
  2634     len2 := otherDigitByteArray size.
  2657     len2 := otherDigitByteArray size.
  2635 
  2658 
  2636     len1 > len2 ifTrue:[
  2659     len1 > len2 ifTrue:[
  2637         lResult := len1
  2660         lResult := len1
  2638     ] ifFalse:[
  2661     ] ifFalse:[
  2639         lResult := (len1 max: len2) + 1.
  2662         lResult := (len1 max: len2) + 1.
  2640     ].
  2663     ].
  2641     result := self class basicNew numberOfDigits:lResult.
  2664     result := self class basicNew numberOfDigits:lResult.
  2642     result sign:newSign.
  2665     result sign:newSign.
  2643     resultDigitByteArray := result digits.
  2666     resultDigitByteArray := result digitBytes.
  2644 
  2667 
  2645     lastDigit := 0.
  2668     lastDigit := 0.
  2646 
  2669 
  2647 %{
  2670 %{
  2648     OBJ _digitByteArray = __INST(digitByteArray);
  2671     OBJ _digitByteArray = __INST(digitByteArray);
  2922      dstIndex "{ Class: SmallInteger }"
  2945      dstIndex "{ Class: SmallInteger }"
  2923      prod     "{ Class: SmallInteger }"
  2946      prod     "{ Class: SmallInteger }"
  2924      v        "{ Class: SmallInteger }"|
  2947      v        "{ Class: SmallInteger }"|
  2925 
  2948 
  2926     len1 := digitByteArray size.
  2949     len1 := digitByteArray size.
  2927     otherDigitByteArray := aLargeInteger digits.
  2950     otherDigitByteArray := aLargeInteger digitBytes.
  2928     len2 := otherDigitByteArray size.
  2951     len2 := otherDigitByteArray size.
  2929 
  2952 
  2930     result := LargeInteger basicNew numberOfDigits:(len1 + len2).
  2953     result := LargeInteger basicNew numberOfDigits:(len1 + len2).
  2931     resultDigitByteArray := result digits.
  2954     resultDigitByteArray := result digitBytes.
  2932     ok := false.
  2955     ok := false.
  2933 %{
  2956 %{
  2934     if (__isByteArray(__INST(digitByteArray))
  2957     if (__isByteArray(__INST(digitByteArray))
  2935      && __isByteArray(otherDigitByteArray)
  2958      && __isByteArray(otherDigitByteArray)
  2936      && __isByteArray(resultDigitByteArray)
  2959      && __isByteArray(resultDigitByteArray)
  3213      newLen "{ Class: SmallInteger }"
  3236      newLen "{ Class: SmallInteger }"
  3214      index  "{ Class: SmallInteger }"
  3237      index  "{ Class: SmallInteger }"
  3215      carry  "{ Class: SmallInteger }"
  3238      carry  "{ Class: SmallInteger }"
  3216      sum    "{ Class: SmallInteger }" |
  3239      sum    "{ Class: SmallInteger }" |
  3217 
  3240 
  3218     otherDigitByteArray := aLargeInteger digits.
  3241     otherDigitByteArray := aLargeInteger digitBytes.
  3219 
  3242 
  3220 %{
  3243 %{
  3221     OBJ _digitByteArray = __INST(digitByteArray);
  3244     OBJ _digitByteArray = __INST(digitByteArray);
  3222 
  3245 
  3223     if (__isByteArray(_digitByteArray)
  3246     if (__isByteArray(_digitByteArray)
  3368             int _comLen3;
  3391             int _comLen3;
  3369 
  3392 
  3370             _comLen3 = _comLen - 3 - 4;
  3393             _comLen3 = _comLen - 3 - 4;
  3371             while (_index <= _comLen3) {
  3394             while (_index <= _comLen3) {
  3372                 unsigned int _sum, _sum2;
  3395                 unsigned int _sum, _sum2;
  3373 		unsigned int __in1A, __in1B, __in2A, __in2B;
  3396                 unsigned int __in1A, __in1B, __in2A, __in2B;
  3374 
  3397 
  3375                 __in1A = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
  3398                 __in1A = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
  3376                 __in2A = ((unsigned int *)(&(_myDigits[_index - 1])))[1];
  3399                 __in2A = ((unsigned int *)(&(_myDigits[_index - 1])))[1];
  3377                 __in1B = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
  3400                 __in1B = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
  3378                 __in2B = ((unsigned int *)(&(_otherDigits[_index - 1])))[1];
  3401                 __in2B = ((unsigned int *)(&(_otherDigits[_index - 1])))[1];
  3408              * accessing bytes at: [index-1][index][index+1][index+2]
  3431              * accessing bytes at: [index-1][index][index+1][index+2]
  3409              */
  3432              */
  3410             _comLen3 = _comLen3 + 4;
  3433             _comLen3 = _comLen3 + 4;
  3411             if (_index <= _comLen3) {
  3434             if (_index <= _comLen3) {
  3412                 unsigned int _sum;
  3435                 unsigned int _sum;
  3413 		unsigned int __inA, __inB;
  3436                 unsigned int __inA, __inB;
  3414 
  3437 
  3415                 __inA = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
  3438                 __inA = ((unsigned int *)(&(_myDigits[_index - 1])))[0];
  3416                 __inB = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
  3439                 __inB = ((unsigned int *)(&(_otherDigits[_index - 1])))[0];
  3417 
  3440 
  3418                 asm ("addl %%edx,%%eax      \n   
  3441                 asm ("addl %%edx,%%eax      \n   
  3663             ]
  3686             ]
  3664         ].
  3687         ].
  3665 
  3688 
  3666         result := self class basicNew numberOfDigits:newLen.
  3689         result := self class basicNew numberOfDigits:newLen.
  3667         result sign:newSign.
  3690         result sign:newSign.
  3668         resultDigitByteArray := result digits.
  3691         resultDigitByteArray := result digitBytes.
  3669 
  3692 
  3670         index := 1.
  3693         index := 1.
  3671         carry := 0.
  3694         carry := 0.
  3672 
  3695 
  3673         done := false.
  3696         done := false.
  3721      notZero
  3744      notZero
  3722     |
  3745     |
  3723 
  3746 
  3724     notZero := false.
  3747     notZero := false.
  3725     len1 := digitByteArray size.
  3748     len1 := digitByteArray size.
  3726     otherDigitByteArray := aLargeInteger digits.
  3749     otherDigitByteArray := aLargeInteger digitBytes.
  3727     len2 := otherDigitByteArray size.
  3750     len2 := otherDigitByteArray size.
  3728     len2 > len1 ifTrue:[
  3751     len2 > len1 ifTrue:[
  3729         [(otherDigitByteArray at:len2) == 0] whileTrue:[
  3752         [(otherDigitByteArray at:len2) == 0] whileTrue:[
  3730             len2 := len2 - 1
  3753             len2 := len2 - 1
  3731         ].
  3754         ].
  4149 ! !
  4172 ! !
  4150 
  4173 
  4151 !LargeInteger class methodsFor:'documentation'!
  4174 !LargeInteger class methodsFor:'documentation'!
  4152 
  4175 
  4153 version
  4176 version
  4154     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.138 1999-09-24 12:27:25 cg Exp $'
  4177     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.139 1999-10-03 08:43:25 cg Exp $'
  4155 ! !
  4178 ! !