LargeInteger.st
changeset 1883 d3fbf4b36be7
parent 1857 94f36a4923db
child 1890 aca066e06680
equal deleted inserted replaced
1882:f5f8a2f201e5 1883:d3fbf4b36be7
   251     "this is a q&d hack - we loose lots of precision here ..."
   251     "this is a q&d hack - we loose lots of precision here ..."
   252     ^ (self asFloat / aNumber asFloat)
   252     ^ (self asFloat / aNumber asFloat)
   253 !
   253 !
   254 
   254 
   255 // aNumber
   255 // aNumber
   256     "return the quotient of the receiver and the argument, aNumber"
   256     "return the quotient of the receiver and the argument, aNumber.
   257 
   257      The result is truncated toward negative infinity and negative,
   258     |otherSign divMod d rem abs "{ Class: SmallInteger }" |
   258      if the operands signs differ."
       
   259 
       
   260     |otherSign divMod d rem abs "{ Class: SmallInteger }" n|
   259 
   261 
   260     otherSign := aNumber sign.
   262     otherSign := aNumber sign.
   261 
   263 
   262     "
   264     "
   263      this is the common case, dividing by a SmallInteger.
   265      this is the common case, dividing by a SmallInteger.
   274             "/ stupid adjust ...
   276             "/ stupid adjust ...
   275             (divMod at:2) == 0 ifFalse:[
   277             (divMod at:2) == 0 ifFalse:[
   276                 ^ (rem sign:-1) - 1
   278                 ^ (rem sign:-1) - 1
   277             ].
   279             ].
   278             ^ rem sign:-1
   280             ^ rem sign:-1
   279         ]
   281         ].
       
   282         n := aNumber asLargeInteger.
       
   283     ] ifFalse:[
       
   284         n := aNumber
   280     ].
   285     ].
   281 
   286 
   282     "
   287     "
   283      if the argument is not a largeInteger, coerce
   288      if the argument is not a largeInteger, coerce
   284     "
   289     "
   285     (aNumber class == self class) ifFalse:[
   290     (n class == self class) ifFalse:[
   286         ^ self retry:#// coercing:aNumber
   291         ^ self retry:#// coercing:aNumber
   287     ].
   292     ].
   288 
   293 
   289     sign < 0 ifTrue:[
   294     sign < 0 ifTrue:[
   290         (sign == otherSign) ifTrue:[^ (self absDiv:aNumber negated) at:1].
   295         (sign == otherSign) ifTrue:[^ (self absDiv:n negated) at:1].
   291     ] ifFalse:[
   296     ] ifFalse:[
   292         (sign == otherSign) ifTrue:[^ (self absDiv:aNumber) at:1].
   297         (sign == otherSign) ifTrue:[^ (self absDiv:n) at:1].
   293     ].
   298     ].
   294 
   299 
   295     divMod := self absDiv:aNumber.
   300     divMod := self absDiv:n.
   296     "/ stupid adjust ...
   301     "/ stupid adjust ...
   297     (divMod at:2) == 0 ifFalse:[
   302     (divMod at:2) == 0 ifFalse:[
   298         ^ ((divMod at:1) sign:-1) - 1
   303         ^ ((divMod at:1) sign:-1) - 1
   299     ].
   304     ].
   300     ^ (divMod at:1) sign:-1
   305     ^ (divMod at:1) sign:-1
   301 
   306 
   302     "
   307     "
   303      9000000000 // 4000000000   => 2
   308      900 // 400  
   304      -9000000000 // 4000000000  => -3
   309      -900 // 400 
   305      9000000000 // -4000000000  => -3
   310      900 // -400  
   306      -9000000000 // -4000000000 => 2
   311      -900 // -400
   307 
   312 
   308      9000000000 quo: 4000000000   => 2
   313      9000000000 // 4000000000
   309      -9000000000 quo: 4000000000  => -2
   314      -9000000000 // 4000000000 
   310      9000000000 quo: -4000000000  => -2
   315      9000000000 // -4000000000 
   311      -9000000000 quo: -4000000000 => 2
   316      -9000000000 // -4000000000
   312     "
   317 
   313 
   318      900 quo: 400   
   314     "Modified: 29.10.1996 / 20:44:23 / cg"
   319      -900 quo: 400  
       
   320      900 quo: -400  
       
   321      -900 quo: -400 
       
   322 
       
   323      9000000000 quo: 4000000000   
       
   324      -9000000000 quo: 4000000000  
       
   325      9000000000 quo: -4000000000  
       
   326      -9000000000 quo: -4000000000 
       
   327     "
       
   328 
       
   329     "Modified: 5.11.1996 / 14:16:46 / cg"
   315 !
   330 !
   316 
   331 
   317 \\ aNumber
   332 \\ aNumber
   318     "return the remainder of division of the receiver by the argument, aNumber"
   333     "return the remainder of division of the receiver by the argument, aNumber.
   319 
   334      The sign of the result is that of aNumber."
   320     |abs|
   335 
       
   336     |abs rem|
   321 
   337 
   322     abs := aNumber abs.
   338     abs := aNumber abs.
   323 
   339 
   324     "
   340     "
   325      this is the common case, dividing by a SmallInteger.
   341      this is the common case, dividing by a SmallInteger.
   326      Use a special method for this case ...
   342      Use a special method for this case ...
   327     "
   343     "
   328     (aNumber class == SmallInteger) ifTrue:[
   344     (aNumber class == SmallInteger) ifTrue:[
   329         (abs between:1 and:16r003fffff) ifTrue:[
   345         (abs between:1 and:16r003fffff) ifTrue:[
   330             ^ ((self absFastDiv:abs) at:2)
   346             rem := (self absFastDiv:abs) at:2.
   331         ]
   347         ] ifFalse:[
   332     ].
   348             rem := (self absDiv:abs asLargeInteger) at:2
   333 
   349         ].
   334     "
   350     ] ifFalse:[
   335      if the argument is not a largeInteger, coerce
   351         "
   336     "
   352          if the argument is not a largeInteger, coerce
   337     (aNumber class == self class) ifFalse:[
   353         "
   338         ^ self retry:#\\ coercing:aNumber
   354         (aNumber class == self class) ifFalse:[
   339     ].
   355             ^ self retry:#\\ coercing:aNumber
   340 
   356         ].
   341     ^ ((self absDiv:abs) at:2)
   357 
   342 
   358         rem := (self absDiv:abs) at:2.
   343     "
   359     ].
   344      9000000000 \\ 4000000000    => 1000000000
   360 
   345      -9000000000 \\ 4000000000   => 1000000000
   361     aNumber negative ifTrue:[
   346      9000000000 \\ -4000000000   => 1000000000
   362         ^ rem negated
   347      -9000000000 \\ -4000000000  => 1000000000
   363     ].
   348 
   364     ^ rem
   349      9000000000 rem: 4000000000   => 1000000000 
   365 
   350      -9000000000 rem: 4000000000  => -1000000000
   366     "
   351      9000000000 rem: -4000000000  => -1000000000 
   367      900 \\ 400    
   352      -9000000000 rem: -4000000000 => 1000000000
   368      -900 \\ 400  
   353     "
   369      900 \\ -400   
   354 
   370      -900 \\ -400  
   355     "Modified: 29.10.1996 / 20:41:35 / cg"
   371 
       
   372      9000000000 \\ 4000000000   
       
   373      -9000000000 \\ 4000000000  
       
   374      9000000000 \\ -4000000000  
       
   375      -9000000000 \\ -4000000000 
       
   376 
       
   377      900 rem: 400    
       
   378      -900 rem: 400  
       
   379      900 rem: -400   
       
   380      -900 rem: -400               
       
   381 
       
   382      9000000000 rem: 4000000000    
       
   383      -9000000000 rem: 4000000000   
       
   384      9000000000 rem: -4000000000   
       
   385      -9000000000 rem: -4000000000  
       
   386     "
       
   387 
       
   388     "Modified: 5.11.1996 / 13:54:32 / cg"
   356 !
   389 !
   357 
   390 
   358 divMod:aNumber
   391 divMod:aNumber
   359     "return an array filled with self // aNumber and
   392     "return an array filled with self // aNumber and
   360      self \\ aNumber.
   393      self \\ aNumber.
   419     newNumber sign:(sign negated).
   452     newNumber sign:(sign negated).
   420     ^ newNumber
   453     ^ newNumber
   421 !
   454 !
   422 
   455 
   423 quo:aNumber
   456 quo:aNumber
   424     "return the quotient of the receiver and the argument, aNumber"
   457     "return the quotient of the receiver and the argument, aNumber.
       
   458      The result is truncated toward zero (which is different from //, which
       
   459      truncates toward negative infinity).
       
   460      The results sign is negative if the receiver has a sign
       
   461      different from the args sign"
   425 
   462 
   426     |otherSign d quo abs "{ Class: SmallInteger }" |
   463     |otherSign d quo abs "{ Class: SmallInteger }" |
   427 
   464 
   428     otherSign := aNumber sign.
   465     otherSign := aNumber sign.
   429 
   466 
   454         (sign == otherSign) ifTrue:[^ (self absDiv:aNumber) at:1].
   491         (sign == otherSign) ifTrue:[^ (self absDiv:aNumber) at:1].
   455     ].
   492     ].
   456     ^ ((self absDiv:aNumber) at:1) sign:-1
   493     ^ ((self absDiv:aNumber) at:1) sign:-1
   457 
   494 
   458     "
   495     "
   459      9000000000 // 4000000000   => 2
   496      900 // 400  
   460      -9000000000 // 4000000000  => -3
   497      -900 // 400  
   461      9000000000 // -4000000000  => -3
   498      900 // -400 
   462      -9000000000 // -4000000000 => 2
   499      -900 // -400  
   463 
   500 
   464      9000000000 quo: 4000000000   => 2
   501      9000000000 // 4000000000     
   465      -9000000000 quo: 4000000000  => -2
   502      -9000000000 // 4000000000    
   466      9000000000 quo: -4000000000  => -2
   503      9000000000 // -4000000000    
   467      -9000000000 quo: -4000000000 => 2
   504      -9000000000 // -4000000000   
   468     "
   505 
   469 
   506      900 quo: 400    
   470     "Modified: 29.10.1996 / 20:39:09 / cg"
   507      -900 quo: 400    
       
   508      900 quo: -400  
       
   509      -900 quo: -400  
       
   510 
       
   511      9000000000 quo: 4000000000   
       
   512      -9000000000 quo: 4000000000  
       
   513      9000000000 quo: -4000000000  
       
   514      -9000000000 quo: -4000000000  
       
   515     "
       
   516 
       
   517     "Modified: 5.11.1996 / 14:14:17 / cg"
   471 !
   518 !
   472 
   519 
   473 rem:aNumber
   520 rem:aNumber
   474     "return the remainder of division of the receiver by the argument, aNumber"
   521     "return the remainder of division of the receiver by the argument, aNumber.
   475 
   522      The returned remainder has the same sign as the receiver."
   476     |otherSign rem abs "{ Class: SmallInteger }" |
   523 
   477 
   524     |rem abs "{ Class: SmallInteger }" |
   478     otherSign := aNumber sign.
       
   479 
   525 
   480     "
   526     "
   481      this is the common case, dividing by a SmallInteger.
   527      this is the common case, dividing by a SmallInteger.
   482      Use a special method for this case ...
   528      Use special code for this case ...
   483     "
   529     "
   484     (aNumber class == SmallInteger) ifTrue:[
   530     (aNumber class == SmallInteger) ifTrue:[
   485         abs := aNumber.
   531         abs := aNumber.
   486         abs := abs abs.
   532         abs := abs abs.
   487         (abs between:1 and:16r003fffff) ifTrue:[
   533         (abs between:1 and:16r003fffff) ifTrue:[
   488             rem := (self absFastDiv:abs) at:2.
   534             rem := (self absFastDiv:abs) at:2.
   489 
   535         ] ifFalse:[
   490             sign < 0 ifTrue:[
   536             rem := (self absDiv:(abs asLargeInteger)) at:2
   491                 (sign == otherSign) ifTrue:[^ rem].
   537         ].
   492                 ^ rem sign:-1
   538     ] ifFalse:[
   493             ].
   539         "
   494             (sign == otherSign) ifTrue:[^ rem].
   540          if the argument is not a largeInteger, coerce
   495             ^ rem sign:-1
   541         "
   496         ]
   542         (aNumber class == self class) ifFalse:[
   497     ].
   543             ^ self retry:#\\ coercing:aNumber
   498 
   544         ].
   499     "
   545 
   500      if the argument is not a largeInteger, coerce
   546         rem := (self absDiv:aNumber) at:2
   501     "
       
   502     (aNumber class == self class) ifFalse:[
       
   503         ^ self retry:#\\ coercing:aNumber
       
   504     ].
   547     ].
   505 
   548 
   506     sign < 0 ifTrue:[
   549     sign < 0 ifTrue:[
   507         (sign == otherSign) ifTrue:[^ (self absDiv:aNumber negated) at:2].
   550         ^ rem sign:-1
   508         ^ ((self absDiv:aNumber) at:2) sign:-1
   551     ].
   509     ].
   552     ^ rem
   510     (sign == otherSign) ifTrue:[^ (self absDiv:aNumber) at:2].
   553 
   511     ^ ((self absDiv:aNumber negated) at:2) sign:-1
   554     "
   512 
   555      900 \\ 400    
   513     "
   556      -900 \\ 400   
   514      9000000000 \\ 4000000000    => 1000000000
   557      900 \\ -400   
   515      -9000000000 \\ 4000000000   => 1000000000
   558      -900 \\ -400  
   516      9000000000 \\ -4000000000   => 1000000000
   559 
   517      -9000000000 \\ -4000000000  => 1000000000
   560      9000000000 \\ 4000000000    
   518 
   561      -9000000000 \\ 4000000000   
   519      9000000000 rem: 4000000000   => 1000000000 
   562      9000000000 \\ -4000000000   
   520      -9000000000 rem: 4000000000  => -1000000000
   563      -9000000000 \\ -4000000000  
   521      9000000000 rem: -4000000000  => -1000000000 
   564 
   522      -9000000000 rem: -4000000000 => 1000000000
   565      900 rem: 400     
   523     "
   566      -900 rem: 400    
   524 
   567      900 rem: -400    
   525     "Modified: 29.10.1996 / 20:40:33 / cg"
   568      -900 rem: -400   
       
   569 
       
   570      9000000000 rem: 4000000000     
       
   571      -9000000000 rem: 4000000000    
       
   572      9000000000 rem: -4000000000    
       
   573      -9000000000 rem: -4000000000   
       
   574     "
       
   575 
       
   576     "Modified: 5.11.1996 / 14:02:59 / cg"
   526 ! !
   577 ! !
   527 
   578 
   528 !LargeInteger methodsFor:'byte access'!
   579 !LargeInteger methodsFor:'byte access'!
   529 
   580 
   530 digitAt:index
   581 digitAt:index
   623     "return the argument as a LargeInteger"
   674     "return the argument as a LargeInteger"
   624 
   675 
   625     ^ aNumber asLargeInteger
   676     ^ aNumber asLargeInteger
   626 !
   677 !
   627 
   678 
   628 normalize
   679 compressed
   629     "if the receiver can be represented as a SmallInteger, return
   680     "if the receiver can be represented as a SmallInteger, return
   630      a SmallInteger with my value; otherwise return self with leading
   681      a SmallInteger with my value; otherwise return self with leading
   631      zeros removed"
   682      zeros removed"
   632 
   683 
   633     |index "{ Class: SmallInteger }" 
   684     |index "{ Class: SmallInteger }" 
   635 
   686 
   636 %{  /* NOCONTEXT */
   687 %{  /* NOCONTEXT */
   637     OBJ t;
   688     OBJ t;
   638 
   689 
   639     if (__INST(sign) == __MKSMALLINT(0)) {
   690     if (__INST(sign) == __MKSMALLINT(0)) {
   640 	RETURN (__MKSMALLINT(0));
   691         RETURN (__MKSMALLINT(0));
   641     }
   692     }
   642 
   693 
   643     t = __INST(digitByteArray);
   694     t = __INST(digitByteArray);
   644     if (__isByteArray(t)) {
   695     if (__isByteArray(t)) {
   645 	unsigned char *_digitBytes = __ByteArrayInstPtr(t)->ba_element;
   696         unsigned char *_digitBytes = __ByteArrayInstPtr(t)->ba_element;
   646 	int _idx = _byteArraySize(t);
   697         int _idx = _byteArraySize(t);
   647 	int _val;
   698         int _val;
   648 
   699 
   649 	while ((_idx > 0) && (_digitBytes[_idx - 1] == 0)) {
   700         while ((_idx > 0) && (_digitBytes[_idx - 1] == 0)) {
   650 	    _idx--;
   701             _idx--;
   651 	}
   702         }
   652 	switch (_idx) {
   703         switch (_idx) {
   653 	    case 0:
   704             case 0:
   654 		RETURN (__MKSMALLINT(0));
   705                 RETURN (__MKSMALLINT(0));
   655 		break;
   706                 break;
   656 
   707 
   657 	    case 1:
   708             case 1:
   658 		_val = _digitBytes[0];
   709                 _val = _digitBytes[0];
   659 		if (__INST(sign) == __MKSMALLINT(-1))
   710                 if (__INST(sign) == __MKSMALLINT(-1))
   660 		    _val = -_val;
   711                     _val = -_val;
   661 		RETURN (__MKSMALLINT(_val));
   712                 RETURN (__MKSMALLINT(_val));
   662                 
   713                 
   663 	    case 2:
   714             case 2:
   664 		_val = (_digitBytes[1]<<8) + _digitBytes[0];
   715                 _val = (_digitBytes[1]<<8) + _digitBytes[0];
   665 		if (__INST(sign) == __MKSMALLINT(-1))
   716                 if (__INST(sign) == __MKSMALLINT(-1))
   666 		    _val = -_val;
   717                     _val = -_val;
   667 		RETURN (__MKSMALLINT(_val));
   718                 RETURN (__MKSMALLINT(_val));
   668 
   719 
   669 	    case 3:
   720             case 3:
   670 		_val = (((_digitBytes[2]<<8) + _digitBytes[1])<<8) + _digitBytes[0];
   721                 _val = (((_digitBytes[2]<<8) + _digitBytes[1])<<8) + _digitBytes[0];
   671 		if (__INST(sign) == __MKSMALLINT(-1))
   722                 if (__INST(sign) == __MKSMALLINT(-1))
   672 		    _val = -_val;
   723                     _val = -_val;
   673 		RETURN (__MKSMALLINT(_val));
   724                 RETURN (__MKSMALLINT(_val));
   674 
   725 
   675 	    case 4:
   726             case 4:
   676 		_val = _digitBytes[3];
   727                 _val = _digitBytes[3];
   677 		if (_val <= 0x40) {
   728                 if (_val <= 0x40) {
   678 		    _val = (((((_val<<8) + _digitBytes[2])<<8) + _digitBytes[1])<<8) + _digitBytes[0];
   729                     _val = (((((_val<<8) + _digitBytes[2])<<8) + _digitBytes[1])<<8) + _digitBytes[0];
   679 		    if (__INST(sign) == __MKSMALLINT(-1))
   730                     if (__INST(sign) == __MKSMALLINT(-1))
   680 			_val = -_val;
   731                         _val = -_val;
   681 		    if ((_val >= _MIN_INT) && (_val <= _MAX_INT)) {
   732                     if ((_val >= _MIN_INT) && (_val <= _MAX_INT)) {
   682 			RETURN (__MKSMALLINT(_val));
   733                         RETURN (__MKSMALLINT(_val));
   683 		    }
   734                     }
   684 		}
   735                 }
   685 		break;
   736                 break;
   686 
   737 
   687 	    default:
   738             default:
   688 		break;
   739                 break;
   689 	}
   740         }
   690     }
   741     }
   691 %}.
   742 %}.
   692     index := digitByteArray size.
   743     index := digitByteArray size.
   693     [(index > 0) and:[(digitByteArray at:index) == 0]] whileTrue:[
   744     [(index > 0) and:[(digitByteArray at:index) == 0]] whileTrue:[
   694 	index := index - 1
   745         index := index - 1
   695     ].
   746     ].
   696 
   747 
   697     (index ~~ digitByteArray size) ifTrue:[
   748     (index ~~ digitByteArray size) ifTrue:[
   698 	digitByteArray := digitByteArray copyFrom:1 to:index
   749         digitByteArray := digitByteArray copyFrom:1 to:index
   699     ].
   750     ].
   700     ^ self
   751     ^ self
   701 !
   752 !
   702 
   753 
   703 value:aSmallInteger
   754 value:aSmallInteger
   947             len := len + 1.
   998             len := len + 1.
   948             resultDigitByteArray basicAt:len put:(carry bitAnd:16rFF).
   999             resultDigitByteArray basicAt:len put:(carry bitAnd:16rFF).
   949             carry := carry bitShift:-8
  1000             carry := carry bitShift:-8
   950         ].
  1001         ].
   951     ].
  1002     ].
   952     ^ result normalize
  1003     ^ result compressed
   953 !
  1004 !
   954 
  1005 
   955 sumFromInteger:anInteger
  1006 sumFromInteger:anInteger
   956     "sent, when anInteger does not know how to add the receiver.
  1007     "sent, when anInteger does not know how to add the receiver.
   957      Return the sum of the receiver and the argument, (which must be a SmallInteger)"
  1008      Return the sum of the receiver and the argument, (which must be a SmallInteger)"
  1006      rem 
  1057      rem 
  1007      count "{ Class: SmallInteger }"
  1058      count "{ Class: SmallInteger }"
  1008      digit "{ Class: SmallInteger }" |
  1059      digit "{ Class: SmallInteger }" |
  1009 
  1060 
  1010     anInteger == 0 ifTrue:[
  1061     anInteger == 0 ifTrue:[
  1011 	^ DivisionByZeroSignal raise
  1062         ^ DivisionByZeroSignal raise
       
  1063     ].
       
  1064 
       
  1065     self = anInteger ifTrue:[
       
  1066         ^ Array with:1 with:0
  1012     ].
  1067     ].
  1013 
  1068 
  1014     tmp1 := self simpleDeepCopy.
  1069     tmp1 := self simpleDeepCopy.
  1015     tmp1 sign:1.
  1070     tmp1 sign:1.
  1016     tmp2 := anInteger simpleDeepCopy.
  1071     tmp2 := anInteger simpleDeepCopy.
  1017     tmp2 sign:1.
  1072     tmp2 sign:1.
  1018 
  1073 
  1019     (tmp1 < tmp2) ifTrue:[
  1074     (tmp1 < tmp2) ifTrue:[
  1020 	^ Array with:0 with:tmp1 
  1075         ^ Array with:0 with:tmp1 
  1021     ].
  1076     ].
  1022 
  1077 
  1023     count := 0.
  1078     count := 0.
  1024     [tmp2 < tmp1] whileTrue:[
  1079     [tmp2 < tmp1] whileTrue:[
  1025 	tmp2 mul256.
  1080         tmp2 mul256.
  1026 	count := count + 1
  1081         count := count + 1
  1027     ].
  1082     ].
  1028 
  1083 
  1029     tmp2 div256.
  1084     tmp2 div256.
  1030 
  1085 
  1031     rem := 0 asLargeInteger. 
  1086     rem := 0 asLargeInteger. 
  1032     rem sign:1.
  1087     rem sign:1.
  1033 
  1088 
  1034     [count == 0] whileFalse:[
  1089     [count == 0] whileFalse:[
  1035 	digit := 0.
  1090         digit := 0.
  1036 	[tmp1 >= tmp2] whileTrue:[
  1091         [tmp1 >= tmp2] whileTrue:[
  1037 	    digit := digit + 1.
  1092             digit := digit + 1.
  1038 	    tmp1 := tmp1 - tmp2
  1093             tmp1 := tmp1 - tmp2
  1039 	].
  1094         ].
  1040 	rem := rem * 256 + digit.
  1095         rem := (rem * 256) + digit.
  1041 	tmp2 div256.
  1096         tmp2 div256.
  1042 	count := count - 1
  1097         count := count - 1
  1043     ].
  1098     ].
  1044     ^ Array with:rem with:tmp1
  1099     ^ Array with:rem with:tmp1
       
  1100 
       
  1101     "Modified: 5.11.1996 / 13:46:14 / cg"
  1045 !
  1102 !
  1046 
  1103 
  1047 absEq:aLargeInteger
  1104 absEq:aLargeInteger
  1048     "return true, if abs(self) = abs(theArgument)"
  1105     "return true, if abs(self) = abs(theArgument)"
  1049 
  1106 
  1161             newDigitByteArray at:i put:tmp1 // aSmallInteger.
  1218             newDigitByteArray at:i put:tmp1 // aSmallInteger.
  1162             prevRest := (tmp1 \\ aSmallInteger).
  1219             prevRest := (tmp1 \\ aSmallInteger).
  1163         ]
  1220         ]
  1164     ].
  1221     ].
  1165 
  1222 
  1166     ^ Array with:result normalize with:prevRest
  1223     ^ Array with:result compressed with:prevRest
  1167 !
  1224 !
  1168 
  1225 
  1169 absFastMinus:aSmallInteger
  1226 absFastMinus:aSmallInteger
  1170     "return a LargeInteger representing abs(self) - abs(theArgument).
  1227     "return a LargeInteger representing abs(self) - abs(theArgument).
  1171      The result is not normalized."
  1228      The result is not normalized."
  1203         resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index).
  1260         resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index).
  1204         index := index + 1
  1261         index := index + 1
  1205     ].
  1262     ].
  1206 
  1263 
  1207     lastDigit == 0 ifTrue:[
  1264     lastDigit == 0 ifTrue:[
  1208         ^ result normalize
  1265         ^ result compressed
  1209     ].
  1266     ].
  1210     ^ result
  1267     ^ result
  1211 
  1268 
  1212     "                                                          
  1269     "                                                          
  1213      12345678900000000000 absFastMinus:1       
  1270      12345678900000000000 absFastMinus:1       
  1215      12345678900000000000 absFastMinus:255
  1272      12345678900000000000 absFastMinus:255
  1216      (SmallInteger maxVal + 1) absFastMinus:1  
  1273      (SmallInteger maxVal + 1) absFastMinus:1  
  1217      (SmallInteger minVal - 1) absFastMinus:1  
  1274      (SmallInteger minVal - 1) absFastMinus:1  
  1218     "
  1275     "
  1219 
  1276 
  1220     "Modified: 20.10.1996 / 18:40:22 / cg"
  1277     "Modified: 5.11.1996 / 14:09:16 / cg"
  1221 !
  1278 !
  1222 
  1279 
  1223 absFastPlus:aSmallInteger
  1280 absFastPlus:aSmallInteger
  1224     "return a LargeInteger representing abs(self) + abs(theArgument).
  1281     "return a LargeInteger representing abs(self) + abs(theArgument).
  1225      The result is not normalized."
  1282      The result is not normalized."
  1249         resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index).
  1306         resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index).
  1250         index := index + 1
  1307         index := index + 1
  1251     ].
  1308     ].
  1252 
  1309 
  1253     lastDigit == 0 ifTrue:[
  1310     lastDigit == 0 ifTrue:[
  1254         ^ result normalize
  1311         ^ result compressed
  1255     ].
  1312     ].
  1256     ^ result
  1313     ^ result
       
  1314 
       
  1315     "Modified: 5.11.1996 / 14:09:19 / cg"
  1257 !
  1316 !
  1258 
  1317 
  1259 absLess:aLargeInteger
  1318 absLess:aLargeInteger
  1260     "return true, if abs(self) < abs(theArgument)"
  1319     "return true, if abs(self) < abs(theArgument)"
  1261 
  1320 
  1373             resultDigitByteArray basicAt:index put:(carry bitAnd:16rFF).
  1432             resultDigitByteArray basicAt:index put:(carry bitAnd:16rFF).
  1374             carry := carry bitShift:-8.
  1433             carry := carry bitShift:-8.
  1375             index := index + 1
  1434             index := index + 1
  1376         ].
  1435         ].
  1377     ].
  1436     ].
  1378     ^ result normalize
  1437     ^ result compressed
  1379 
  1438 
  1380     "Modified: 1.7.1996 / 21:07:17 / cg"
  1439     "Modified: 5.11.1996 / 14:09:25 / cg"
  1381 !
  1440 !
  1382 
  1441 
  1383 absMul:aLargeInteger
  1442 absMul:aLargeInteger
  1384     "return a LargeInteger representing abs(self) * abs(theArgument)"
  1443     "return a LargeInteger representing abs(self) * abs(theArgument)"
  1385 
  1444 
  1402 %{
  1461 %{
  1403     if (__isByteArray(__INST(digitByteArray))
  1462     if (__isByteArray(__INST(digitByteArray))
  1404      && __isByteArray(otherDigitByteArray)
  1463      && __isByteArray(otherDigitByteArray)
  1405      && __isByteArray(resultDigitByteArray)
  1464      && __isByteArray(resultDigitByteArray)
  1406      && __bothSmallInteger(len1, len2)) {
  1465      && __bothSmallInteger(len1, len2)) {
  1407 	unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
  1466         unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
  1408 	unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  1467         unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  1409 	unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  1468         unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  1410 	int _index1, _index2, _dstIndex, _idx;
  1469         int _index1, _index2, _dstIndex, _idx;
  1411 	unsigned _prod, _carry, _v;
  1470         unsigned _prod, _carry, _v;
  1412 
  1471 
  1413 	for (_index1 = 0; _index1 < __intVal(len1); _index1++) {
  1472         for (_index1 = 0; _index1 < __intVal(len1); _index1++) {
  1414 	    for (_index2 = 0; _index2 < __intVal(len2); _index2++) {
  1473             for (_index2 = 0; _index2 < __intVal(len2); _index2++) {
  1415 		_dstIndex = _index1 + _index2;
  1474                 _dstIndex = _index1 + _index2;
  1416 		_prod = myBytes[_index1] * otherBytes[_index2];
  1475                 _prod = myBytes[_index1] * otherBytes[_index2];
  1417 		_prod += resultBytes[_dstIndex];
  1476                 _prod += resultBytes[_dstIndex];
  1418 		resultBytes[_dstIndex] = _prod & 0xFF;
  1477                 resultBytes[_dstIndex] = _prod & 0xFF;
  1419 		_carry = _prod >> 8;
  1478                 _carry = _prod >> 8;
  1420 		if (_carry) {
  1479                 if (_carry) {
  1421 		    _idx = _dstIndex + 1;
  1480                     _idx = _dstIndex + 1;
  1422 		    while (_carry) {
  1481                     while (_carry) {
  1423 			_v = resultBytes[_idx] + _carry;
  1482                         _v = resultBytes[_idx] + _carry;
  1424 			resultBytes[_idx] = _v & 0xFF;
  1483                         resultBytes[_idx] = _v & 0xFF;
  1425 			_carry = _v >> 8;
  1484                         _carry = _v >> 8;
  1426 			_idx = _idx + 1;
  1485                         _idx = _idx + 1;
  1427 		    }
  1486                     }
  1428 		}
  1487                 }
  1429 	    }
  1488             }
  1430 	}
  1489         }
  1431 	ok = true;
  1490         ok = true;
  1432     }
  1491     }
  1433 %}.
  1492 %}.
  1434     ok ifFalse:[
  1493     ok ifFalse:[
  1435 	1 to:len1 do:[:index1 |
  1494         1 to:len1 do:[:index1 |
  1436 	    1 to:len2 do:[:index2 |
  1495             1 to:len2 do:[:index2 |
  1437 		dstIndex := index1 + index2 - 1.
  1496                 dstIndex := index1 + index2 - 1.
  1438 		prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
  1497                 prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2).
  1439 		prod := prod + (resultDigitByteArray basicAt:dstIndex).
  1498                 prod := prod + (resultDigitByteArray basicAt:dstIndex).
  1440 		resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
  1499                 resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF).
  1441 		carry := prod bitShift:-8.
  1500                 carry := prod bitShift:-8.
  1442 		carry ~~ 0 ifTrue:[
  1501                 carry ~~ 0 ifTrue:[
  1443 		    idx := dstIndex + 1.
  1502                     idx := dstIndex + 1.
  1444 		    [carry ~~ 0] whileTrue:[
  1503                     [carry ~~ 0] whileTrue:[
  1445 			v := (resultDigitByteArray basicAt:idx) + carry.
  1504                         v := (resultDigitByteArray basicAt:idx) + carry.
  1446 			resultDigitByteArray basicAt:idx put:(v bitAnd:255).
  1505                         resultDigitByteArray basicAt:idx put:(v bitAnd:255).
  1447 			carry := v bitShift:-8.
  1506                         carry := v bitShift:-8.
  1448 			idx := idx + 1
  1507                         idx := idx + 1
  1449 		    ]
  1508                     ]
  1450 		]
  1509                 ]
  1451 	    ]
  1510             ]
  1452 	].
  1511         ].
  1453     ].
  1512     ].
  1454     ^ result normalize
  1513     ^ result compressed
  1455 !
  1514 !
  1456 
  1515 
  1457 absPlus:aLargeInteger
  1516 absPlus:aLargeInteger
  1458     "return a LargeInteger representing abs(self) + abs(theArgument)"
  1517     "return a LargeInteger representing abs(self) + abs(theArgument)"
  1459 
  1518 
  1474     index := 1.
  1533     index := 1.
  1475     carry := 0.
  1534     carry := 0.
  1476 
  1535 
  1477     done := false.
  1536     done := false.
  1478     [done] whileFalse:[
  1537     [done] whileFalse:[
  1479 	sum := carry.
  1538         sum := carry.
  1480 	(index <= len1) ifTrue:[
  1539         (index <= len1) ifTrue:[
  1481 	    sum := sum + (digitByteArray basicAt:index).
  1540             sum := sum + (digitByteArray basicAt:index).
  1482 	    (index <= len2) ifTrue:[
  1541             (index <= len2) ifTrue:[
  1483 		sum := sum + (otherDigitByteArray basicAt:index)
  1542                 sum := sum + (otherDigitByteArray basicAt:index)
  1484 	    ]
  1543             ]
  1485 	] ifFalse:[
  1544         ] ifFalse:[
  1486 	    (index <= len2) ifTrue:[
  1545             (index <= len2) ifTrue:[
  1487 		sum := sum + (otherDigitByteArray basicAt:index)
  1546                 sum := sum + (otherDigitByteArray basicAt:index)
  1488 	    ] ifFalse:[
  1547             ] ifFalse:[
  1489 		"end reached"
  1548                 "end reached"
  1490 		done := true
  1549                 done := true
  1491 	    ]
  1550             ]
  1492 	].
  1551         ].
  1493 	(sum >= 16r100) ifTrue:[
  1552         (sum >= 16r100) ifTrue:[
  1494 	    carry := 1.
  1553             carry := 1.
  1495 	    sum := sum - 16r100
  1554             sum := sum - 16r100
  1496 	] ifFalse:[
  1555         ] ifFalse:[
  1497 	    carry := 0
  1556             carry := 0
  1498 	].
  1557         ].
  1499 	resultDigitByteArray basicAt:index put:sum.
  1558         resultDigitByteArray basicAt:index put:sum.
  1500 	index := index + 1
  1559         index := index + 1
  1501     ].
  1560     ].
  1502     ^ result normalize
  1561     ^ result compressed
       
  1562 
       
  1563     "Modified: 5.11.1996 / 14:09:34 / cg"
  1503 !
  1564 !
  1504 
  1565 
  1505 div256
  1566 div256
  1506     "destructively divide the receiver by 256.
  1567     "destructively divide the receiver by 256.
  1507      private - used for division only"
  1568      private - used for division only"
  1575 ! !
  1636 ! !
  1576 
  1637 
  1577 !LargeInteger class methodsFor:'documentation'!
  1638 !LargeInteger class methodsFor:'documentation'!
  1578 
  1639 
  1579 version
  1640 version
  1580     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.35 1996-11-01 19:00:10 cg Exp $'
  1641     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.36 1996-11-05 13:31:25 cg Exp $'
  1581 ! !
  1642 ! !