LargeInteger.st
changeset 11927 75c9deec4a70
parent 11731 f3adbab61060
child 11959 1ff0e6f908d9
equal deleted inserted replaced
11926:295e8bb99fde 11927:75c9deec4a70
   313     "
   313     "
   314      this is the common case, multiplying with SmallInteger.
   314      this is the common case, multiplying with SmallInteger.
   315      Use a special method for this case ...
   315      Use a special method for this case ...
   316     "
   316     "
   317     ((numberClass := aNumber class) == SmallInteger) ifTrue:[
   317     ((numberClass := aNumber class) == SmallInteger) ifTrue:[
   318         ^ self productFromInteger:aNumber
   318 	^ self productFromInteger:aNumber
   319     ].
   319     ].
   320 
   320 
   321     "
   321     "
   322      if the argument is not a largeInteger, coerce
   322      if the argument is not a largeInteger, coerce
   323     "
   323     "
   324     (numberClass == self class) ifFalse:[
   324     (numberClass == self class) ifFalse:[
   325         ^ self retry:#* coercing:aNumber
   325 	^ self retry:#* coercing:aNumber
   326     ].
   326     ].
   327 
   327 
   328     otherSign := aNumber sign.
   328     otherSign := aNumber sign.
   329     (sign == otherSign) ifTrue:[^ self absMul:aNumber].
   329     (sign == otherSign) ifTrue:[^ self absMul:aNumber].
   330     (otherSign == 0) ifTrue:[^ 0].
   330     (otherSign == 0) ifTrue:[^ 0].
   386     "
   386     "
   387      this is the common case, subtracting a SmallInteger.
   387      this is the common case, subtracting a SmallInteger.
   388      Use a special method for this case ...
   388      Use a special method for this case ...
   389     "
   389     "
   390     ((numberClass := aNumber class) == SmallInteger) ifTrue:[
   390     ((numberClass := aNumber class) == SmallInteger) ifTrue:[
   391         sign > 0 ifTrue:[
   391 	sign > 0 ifTrue:[
   392             aNumber > 0 ifTrue:[
   392 	    aNumber > 0 ifTrue:[
   393                 ^ self absFastMinus:aNumber sign:1
   393 		^ self absFastMinus:aNumber sign:1
   394             ].
   394 	    ].
   395             ^ self absFastPlus:aNumber sign:1
   395 	    ^ self absFastPlus:aNumber sign:1
   396         ].
   396 	].
   397         aNumber > 0 ifTrue:[
   397 	aNumber > 0 ifTrue:[
   398             ^ self absFastPlus:aNumber sign:-1
   398 	    ^ self absFastPlus:aNumber sign:-1
   399         ].
   399 	].
   400         ^ self absFastMinus:aNumber sign:-1
   400 	^ self absFastMinus:aNumber sign:-1
   401     ].
   401     ].
   402 
   402 
   403     "
   403     "
   404      if the argument is not a largeInteger, coerce
   404      if the argument is not a largeInteger, coerce
   405     "
   405     "
   406     (numberClass == self class) ifFalse:[
   406     (numberClass == self class) ifFalse:[
   407         ^ self retry:#- coercing:aNumber
   407 	^ self retry:#- coercing:aNumber
   408     ].
   408     ].
   409 
   409 
   410     otherSign := aNumber sign.
   410     otherSign := aNumber sign.
   411     (sign > 0) ifTrue:[
   411     (sign > 0) ifTrue:[
   412         "I am positive"
   412 	"I am positive"
   413         (otherSign > 0) ifTrue:[
   413 	(otherSign > 0) ifTrue:[
   414             "+large - +large"
   414 	    "+large - +large"
   415             ^ self absMinus:aNumber sign:1
   415 	    ^ self absMinus:aNumber sign:1
   416         ].
   416 	].
   417         (otherSign < 0) ifTrue:[
   417 	(otherSign < 0) ifTrue:[
   418             "+large - -large"
   418 	    "+large - -large"
   419             ^ self absPlus:aNumber sign:1
   419 	    ^ self absPlus:aNumber sign:1
   420         ].
   420 	].
   421         "should not happen"
   421 	"should not happen"
   422         ^ self
   422 	^ self
   423     ].
   423     ].
   424     "I am negative"
   424     "I am negative"
   425     (otherSign > 0) ifTrue:[
   425     (otherSign > 0) ifTrue:[
   426         "-large - +large"
   426 	"-large - +large"
   427         ^ self absPlus:aNumber sign:-1
   427 	^ self absPlus:aNumber sign:-1
   428     ].
   428     ].
   429     (otherSign < 0) ifTrue:[
   429     (otherSign < 0) ifTrue:[
   430         "-large - -large"
   430 	"-large - -large"
   431         ^ self absMinus:aNumber sign:-1
   431 	^ self absMinus:aNumber sign:-1
   432     ].
   432     ].
   433     ^ self
   433     ^ self
   434 
   434 
   435     "
   435     "
   436      12345678901234567890 - 0
   436      12345678901234567890 - 0
   870 bitAnd:anInteger
   870 bitAnd:anInteger
   871     "return the bitwise-and of the receiver and the argument, anInteger"
   871     "return the bitwise-and of the receiver and the argument, anInteger"
   872 
   872 
   873 %{  /* NOCONTEXT */
   873 %{  /* NOCONTEXT */
   874     if (__isSmallInteger(anInteger)) {
   874     if (__isSmallInteger(anInteger)) {
   875         INT v2 = __intVal(anInteger);
   875 	INT v2 = __intVal(anInteger);
   876         INT v1;
   876 	INT v1;
   877 #if defined(__LSBFIRST__)
   877 #if defined(__LSBFIRST__)
   878         v1 = *(INT *)(__byteArrayVal(__INST(digitByteArray)));
   878 	v1 = *(INT *)(__byteArrayVal(__INST(digitByteArray)));
   879 #else
   879 #else
   880         unsigned char *digits = (unsigned char *)(__byteArrayVal(__INST(digitByteArray)));
   880 	unsigned char *digits = (unsigned char *)(__byteArrayVal(__INST(digitByteArray)));
   881 
   881 
   882         v1 = digits[0] & 0xFF;
   882 	v1 = digits[0] & 0xFF;
   883         v1 = v1 | ((digits[1] & 0xFF)<<8);
   883 	v1 = v1 | ((digits[1] & 0xFF)<<8);
   884         v1 = v1 | ((digits[2] & 0xFF)<<16);
   884 	v1 = v1 | ((digits[2] & 0xFF)<<16);
   885         v1 = v1 | ((digits[3] & 0xFF)<<24);
   885 	v1 = v1 | ((digits[3] & 0xFF)<<24);
   886 # if (__POINTER_SIZE__ == 8)
   886 # if (__POINTER_SIZE__ == 8)
   887         v1 = v1 | ((digits[4] & 0xFF)<<32);
   887 	v1 = v1 | ((digits[4] & 0xFF)<<32);
   888         v1 = v1 | ((digits[5] & 0xFF)<<40);
   888 	v1 = v1 | ((digits[5] & 0xFF)<<40);
   889         v1 = v1 | ((digits[6] & 0xFF)<<48);
   889 	v1 = v1 | ((digits[6] & 0xFF)<<48);
   890         v1 = v1 | ((digits[7] & 0xFF)<<56);
   890 	v1 = v1 | ((digits[7] & 0xFF)<<56);
   891  #endif
   891  #endif
   892 #endif
   892 #endif
   893         RETURN ( __mkSmallInteger(v1 & v2) );
   893 	RETURN ( __mkSmallInteger(v1 & v2) );
   894     }
   894     }
   895 %}.
   895 %}.
   896     ^ super bitAnd:anInteger
   896     ^ super bitAnd:anInteger
   897 
   897 
   898     "
   898     "
   910 !
   910 !
   911 
   911 
   912 bitAt:anIntegerIndex
   912 bitAt:anIntegerIndex
   913     "return the value of the index's bit (index starts at 1) as 0 or 1.
   913     "return the value of the index's bit (index starts at 1) as 0 or 1.
   914      Notice: the result of bitAt: on negative receivers is not
   914      Notice: the result of bitAt: on negative receivers is not
   915              defined in the language standard (since the implementation
   915 	     defined in the language standard (since the implementation
   916              is free to choose any internal representation for integers)"
   916 	     is free to choose any internal representation for integers)"
   917 
   917 
   918 %{  /* NOCONTEXT */
   918 %{  /* NOCONTEXT */
   919     if (__isSmallInteger(anIntegerIndex)) {
   919     if (__isSmallInteger(anIntegerIndex)) {
   920         INT idx = __smallIntegerVal(anIntegerIndex) - 1;
   920 	INT idx = __smallIntegerVal(anIntegerIndex) - 1;
   921 
   921 
   922         if (idx >= 0) {
   922 	if (idx >= 0) {
   923             int v1;
   923 	    int v1;
   924             int byteOffset = idx / 8;
   924 	    int byteOffset = idx / 8;
   925             int digitLen   = __stringSize(__INST(digitByteArray));
   925 	    int digitLen   = __stringSize(__INST(digitByteArray));
   926 
   926 
   927             if (digitLen < byteOffset) {
   927 	    if (digitLen < byteOffset) {
   928                 RETURN(__mkSmallInteger(0));
   928 		RETURN(__mkSmallInteger(0));
   929             }
   929 	    }
   930 
   930 
   931             v1 = (__byteArrayVal(__INST(digitByteArray)))[byteOffset];
   931 	    v1 = (__byteArrayVal(__INST(digitByteArray)))[byteOffset];
   932             if (v1 & (1 << (idx % 8))) {
   932 	    if (v1 & (1 << (idx % 8))) {
   933                 RETURN(__mkSmallInteger(1));
   933 		RETURN(__mkSmallInteger(1));
   934             } else {
   934 	    } else {
   935                 RETURN(__mkSmallInteger(0));
   935 		RETURN(__mkSmallInteger(0));
   936             }
   936 	    }
   937         }
   937 	}
   938     }
   938     }
   939 %}.
   939 %}.
   940     ^ super bitAt:anIntegerIndex
   940     ^ super bitAt:anIntegerIndex
   941 
   941 
   942     "
   942     "
  1008 %{
  1008 %{
  1009     /*
  1009     /*
  1010      * quickly advance over full 0-words
  1010      * quickly advance over full 0-words
  1011      */
  1011      */
  1012     if (__isByteArray(__INST(digitByteArray))) {
  1012     if (__isByteArray(__INST(digitByteArray))) {
  1013         int __sz = __intVal(sz);
  1013 	int __sz = __intVal(sz);
  1014         unsigned char *__bP = __byteArrayVal(__INST(digitByteArray));
  1014 	unsigned char *__bP = __byteArrayVal(__INST(digitByteArray));
  1015         unsigned char *__bP0 = __bP;
  1015 	unsigned char *__bP0 = __bP;
  1016 
  1016 
  1017 #ifdef __UNROLL_LOOPS__
  1017 #ifdef __UNROLL_LOOPS__
  1018         while (__sz > (sizeof(INT) * 4)) {
  1018 	while (__sz > (sizeof(INT) * 4)) {
  1019             if ( ((INT *)__bP)[0] != 0 ) break;
  1019 	    if ( ((INT *)__bP)[0] != 0 ) break;
  1020             if ( ((INT *)__bP)[1] != 0 ) {
  1020 	    if ( ((INT *)__bP)[1] != 0 ) {
  1021                 __sz -= sizeof(INT);
  1021 		__sz -= sizeof(INT);
  1022                 __bP += sizeof(INT);
  1022 		__bP += sizeof(INT);
  1023                 break;
  1023 		break;
  1024             }
  1024 	    }
  1025             if ( ((INT *)__bP)[2] != 0 ) {
  1025 	    if ( ((INT *)__bP)[2] != 0 ) {
  1026                 __sz -= sizeof(INT) * 2;
  1026 		__sz -= sizeof(INT) * 2;
  1027                 __bP += sizeof(INT) * 2;
  1027 		__bP += sizeof(INT) * 2;
  1028                 break;
  1028 		break;
  1029             }
  1029 	    }
  1030             if ( ((INT *)__bP)[3] != 0 ) {
  1030 	    if ( ((INT *)__bP)[3] != 0 ) {
  1031                 __sz -= sizeof(INT) * 3;
  1031 		__sz -= sizeof(INT) * 3;
  1032                 __bP += sizeof(INT) * 3;
  1032 		__bP += sizeof(INT) * 3;
  1033                 break;
  1033 		break;
  1034             }
  1034 	    }
  1035             __sz -= sizeof(INT) * 4;
  1035 	    __sz -= sizeof(INT) * 4;
  1036             __bP += sizeof(INT) * 4;
  1036 	    __bP += sizeof(INT) * 4;
  1037         }
  1037 	}
  1038 #endif
  1038 #endif
  1039         while (__sz > sizeof(INT)) {
  1039 	while (__sz > sizeof(INT)) {
  1040             if ( ((INT *)__bP)[0] != 0 ) break;
  1040 	    if ( ((INT *)__bP)[0] != 0 ) break;
  1041             __sz -= sizeof(INT);
  1041 	    __sz -= sizeof(INT);
  1042             __bP += sizeof(INT);
  1042 	    __bP += sizeof(INT);
  1043         }
  1043 	}
  1044         while (__sz > 0) {
  1044 	while (__sz > 0) {
  1045             unsigned int c;
  1045 	    unsigned int c;
  1046 
  1046 
  1047             if ( (c = *__bP) != 0 ) {
  1047 	    if ( (c = *__bP) != 0 ) {
  1048                 int bitIdx = (__bP - __bP0) * 8;
  1048 		int bitIdx = (__bP - __bP0) * 8;
  1049 #ifdef __BSF
  1049 #ifdef __BSF
  1050                 {
  1050 		{
  1051                     int index;
  1051 		    int index;
  1052                     int t = c;
  1052 		    int t = c;
  1053 
  1053 
  1054                     index = __BSF(t);
  1054 		    index = __BSF(t);
  1055                     RETURN ( __mkSmallInteger(index + 1 + bitIdx) );
  1055 		    RETURN ( __mkSmallInteger(index + 1 + bitIdx) );
  1056                 }
  1056 		}
  1057 #else
  1057 #else
  1058                 if (c & 0x0F) {
  1058 		if (c & 0x0F) {
  1059                     if (c & 0x03) {
  1059 		    if (c & 0x03) {
  1060                         if (c & 0x01) {
  1060 			if (c & 0x01) {
  1061                             RETURN ( __mkSmallInteger( bitIdx + 1) );
  1061 			    RETURN ( __mkSmallInteger( bitIdx + 1) );
  1062                         } else {
  1062 			} else {
  1063                             RETURN ( __mkSmallInteger( bitIdx + 2) );
  1063 			    RETURN ( __mkSmallInteger( bitIdx + 2) );
  1064                         }
  1064 			}
  1065                     } else {
  1065 		    } else {
  1066                         if (c & 0x04) {
  1066 			if (c & 0x04) {
  1067                             RETURN ( __mkSmallInteger( bitIdx + 3) );
  1067 			    RETURN ( __mkSmallInteger( bitIdx + 3) );
  1068                         } else {
  1068 			} else {
  1069                             RETURN ( __mkSmallInteger( bitIdx + 4) );
  1069 			    RETURN ( __mkSmallInteger( bitIdx + 4) );
  1070                         }
  1070 			}
  1071                     }
  1071 		    }
  1072                 } else {
  1072 		} else {
  1073                     if (c & 0x30) {
  1073 		    if (c & 0x30) {
  1074                         if (c & 0x10) {
  1074 			if (c & 0x10) {
  1075                             RETURN ( __mkSmallInteger( bitIdx + 5) );
  1075 			    RETURN ( __mkSmallInteger( bitIdx + 5) );
  1076                         } else {
  1076 			} else {
  1077                             RETURN ( __mkSmallInteger( bitIdx + 6) );
  1077 			    RETURN ( __mkSmallInteger( bitIdx + 6) );
  1078                         }
  1078 			}
  1079                     } else {
  1079 		    } else {
  1080                         if (c & 0x40) {
  1080 			if (c & 0x40) {
  1081                             RETURN ( __mkSmallInteger( bitIdx + 7) );
  1081 			    RETURN ( __mkSmallInteger( bitIdx + 7) );
  1082                         } else {
  1082 			} else {
  1083                             RETURN ( __mkSmallInteger( bitIdx + 8) );
  1083 			    RETURN ( __mkSmallInteger( bitIdx + 8) );
  1084                         }
  1084 			}
  1085                     }
  1085 		    }
  1086                 }
  1086 		}
  1087 #endif
  1087 #endif
  1088                 break;
  1088 		break;
  1089             }
  1089 	    }
  1090             __sz--;
  1090 	    __sz--;
  1091             __bP++;
  1091 	    __bP++;
  1092         }
  1092 	}
  1093         idx0 = __mkSmallInteger( __bP - __bP0 + 1 );
  1093 	idx0 = __mkSmallInteger( __bP - __bP0 + 1 );
  1094     }
  1094     }
  1095 %}.
  1095 %}.
  1096     "/ never actually reached
  1096     "/ never actually reached
  1097     idx0 to:sz do:[:digitIndex |
  1097     idx0 to:sz do:[:digitIndex |
  1098         (byte := digitByteArray at:digitIndex) ~~ 0 ifTrue:[
  1098 	(byte := digitByteArray at:digitIndex) ~~ 0 ifTrue:[
  1099             ^ (digitIndex-1)*8 + (byte lowBit)
  1099 	    ^ (digitIndex-1)*8 + (byte lowBit)
  1100         ]
  1100 	]
  1101     ].
  1101     ].
  1102     ^ 0 "/ should not happen
  1102     ^ 0 "/ should not happen
  1103 
  1103 
  1104     "
  1104     "
  1105      (1 bitShift:0) lowBit     
  1105      (1 bitShift:0) lowBit
  1106      (1 bitShift:10) lowBit
  1106      (1 bitShift:10) lowBit
  1107      (1 bitShift:20) lowBit
  1107      (1 bitShift:20) lowBit
  1108      (1 bitShift:30) lowBit
  1108      (1 bitShift:30) lowBit
  1109      (1 bitShift:30) highBit
  1109      (1 bitShift:30) highBit
  1110      (1 bitShift:31) lowBit
  1110      (1 bitShift:31) lowBit
  1112      (1 bitShift:32) lowBit
  1112      (1 bitShift:32) lowBit
  1113      (1 bitShift:32) highBit
  1113      (1 bitShift:32) highBit
  1114      (1 bitShift:33) lowBit
  1114      (1 bitShift:33) lowBit
  1115      (1 bitShift:33) highBit
  1115      (1 bitShift:33) highBit
  1116      (1 bitShift:64) lowBit
  1116      (1 bitShift:64) lowBit
  1117      (1 bitShift:64) highBit  
  1117      (1 bitShift:64) highBit
  1118      (1 bitShift:1000) lowBit
  1118      (1 bitShift:1000) lowBit
  1119      (1 bitShift:1000) highBit
  1119      (1 bitShift:1000) highBit
  1120      ((1 bitShift:64)-1) lowBit
  1120      ((1 bitShift:64)-1) lowBit
  1121      ((1 bitShift:64)-1) highBit
  1121      ((1 bitShift:64)-1) highBit
  1122 
  1122 
  1123      1 to:1000 do:[:idx |
  1123      1 to:1000 do:[:idx |
  1124         self assert:(( 1 bitShift:idx) lowBit = (idx+1)).
  1124 	self assert:(( 1 bitShift:idx) lowBit = (idx+1)).
  1125         self assert:(( 1 bitShift:idx) lowBit = ( 1 bitShift:idx) highBit).
  1125 	self assert:(( 1 bitShift:idx) lowBit = ( 1 bitShift:idx) highBit).
  1126         self assert:(( 3 bitShift:idx) lowBit = (idx+1)).
  1126 	self assert:(( 3 bitShift:idx) lowBit = (idx+1)).
  1127         self assert:(( 7 bitShift:idx) lowBit = (idx+1)).
  1127 	self assert:(( 7 bitShift:idx) lowBit = (idx+1)).
  1128         self assert:(( 15 bitShift:idx) lowBit = (idx+1)).
  1128 	self assert:(( 15 bitShift:idx) lowBit = (idx+1)).
  1129         self assert:(( 31 bitShift:idx) lowBit = (idx+1)).
  1129 	self assert:(( 31 bitShift:idx) lowBit = (idx+1)).
  1130         self assert:(( 63 bitShift:idx) lowBit = (idx+1)).
  1130 	self assert:(( 63 bitShift:idx) lowBit = (idx+1)).
  1131         self assert:(( 127 bitShift:idx) lowBit = (idx+1)).
  1131 	self assert:(( 127 bitShift:idx) lowBit = (idx+1)).
  1132         self assert:(( 255 bitShift:idx) lowBit = (idx+1)).
  1132 	self assert:(( 255 bitShift:idx) lowBit = (idx+1)).
  1133      ]
  1133      ]
  1134 
  1134 
  1135      |num|
  1135      |num|
  1136 
  1136 
  1137      num := (1 bitShift:1000).
  1137      num := (1 bitShift:1000).
  1138      Time millisecondsToRun:[
  1138      Time millisecondsToRun:[
  1139         100000 timesRepeat:[
  1139 	100000 timesRepeat:[
  1140             num lowBit
  1140 	    num lowBit
  1141         ]
  1141 	]
  1142      ]
  1142      ]
  1143     "
  1143     "
  1144 
  1144 
  1145     "Modified: 14.8.1997 / 11:55:34 / cg"
  1145     "Modified: 14.8.1997 / 11:55:34 / cg"
  1146 !
  1146 !
  1152      but a new number is returned. Should be named #withBitSet:"
  1152      but a new number is returned. Should be named #withBitSet:"
  1153 
  1153 
  1154     |myDigitLength newDigitLength newDigitBytes byteIndexOfBitToSet|
  1154     |myDigitLength newDigitLength newDigitBytes byteIndexOfBitToSet|
  1155 
  1155 
  1156     index <= 0 ifTrue:[
  1156     index <= 0 ifTrue:[
  1157         ^ SubscriptOutOfBoundsSignal 
  1157 	^ SubscriptOutOfBoundsSignal
  1158                 raiseRequestWith:index
  1158 		raiseRequestWith:index
  1159                 errorString:'index out of bounds'
  1159 		errorString:'index out of bounds'
  1160     ].
  1160     ].
  1161 
  1161 
  1162     myDigitLength := digitByteArray size.
  1162     myDigitLength := digitByteArray size.
  1163     byteIndexOfBitToSet := ((index-1)//8)+1.
  1163     byteIndexOfBitToSet := ((index-1)//8)+1.
  1164     byteIndexOfBitToSet > myDigitLength ifTrue:[
  1164     byteIndexOfBitToSet > myDigitLength ifTrue:[
  1165         newDigitLength := myDigitLength max:byteIndexOfBitToSet.
  1165 	newDigitLength := myDigitLength max:byteIndexOfBitToSet.
  1166         newDigitBytes := ByteArray new:newDigitLength.
  1166 	newDigitBytes := ByteArray new:newDigitLength.
  1167         newDigitBytes replaceFrom:1 to:myDigitLength with:digitByteArray startingAt:1.
  1167 	newDigitBytes replaceFrom:1 to:myDigitLength with:digitByteArray startingAt:1.
  1168     ] ifFalse:[
  1168     ] ifFalse:[
  1169         newDigitBytes := digitByteArray copy
  1169 	newDigitBytes := digitByteArray copy
  1170     ].
  1170     ].
  1171     newDigitBytes 
  1171     newDigitBytes
  1172         at:byteIndexOfBitToSet     
  1172 	at:byteIndexOfBitToSet
  1173         put:((newDigitBytes at:byteIndexOfBitToSet) setBit:(((index-1)\\8)+1)).
  1173 	put:((newDigitBytes at:byteIndexOfBitToSet) setBit:(((index-1)\\8)+1)).
  1174     ^ (self class digitBytes:newDigitBytes) sign:sign
  1174     ^ (self class digitBytes:newDigitBytes) sign:sign
  1175 
  1175 
  1176     "
  1176     "
  1177      TestCase assert:( 16r80000000 setBit:3  ) = 16r80000004 
  1177      TestCase assert:( 16r80000000 setBit:3  ) = 16r80000004
  1178      TestCase assert:( 16r80000000 setBit:33 ) = 16r180000000 
  1178      TestCase assert:( 16r80000000 setBit:33 ) = 16r180000000
  1179     "
  1179     "
  1180 ! !
  1180 ! !
  1181 
  1181 
  1182 !LargeInteger methodsFor:'byte access'!
  1182 !LargeInteger methodsFor:'byte access'!
  1183 
  1183 
  1628     "return true, if the argument, aNumber is greater than the receiver"
  1628     "return true, if the argument, aNumber is greater than the receiver"
  1629 
  1629 
  1630     |otherSign|
  1630     |otherSign|
  1631 
  1631 
  1632     (aNumber class == self class) ifTrue:[
  1632     (aNumber class == self class) ifTrue:[
  1633         otherSign := aNumber sign.
  1633 	otherSign := aNumber sign.
  1634 
  1634 
  1635         (sign > 0) ifTrue:[
  1635 	(sign > 0) ifTrue:[
  1636             "I am positive"
  1636 	    "I am positive"
  1637             (otherSign > 0) ifTrue:[^ self absLess:aNumber].
  1637 	    (otherSign > 0) ifTrue:[^ self absLess:aNumber].
  1638             ^ false "aNumber is <= 0"
  1638 	    ^ false "aNumber is <= 0"
  1639         ].
  1639 	].
  1640         "I am negative"
  1640 	"I am negative"
  1641         (otherSign > 0) ifTrue:[^ true].
  1641 	(otherSign > 0) ifTrue:[^ true].
  1642         (otherSign == 0) ifTrue:[^ true].
  1642 	(otherSign == 0) ifTrue:[^ true].
  1643         ^ (aNumber absLess:self)
  1643 	^ (aNumber absLess:self)
  1644     ].
  1644     ].
  1645     (aNumber class == SmallInteger) ifTrue:[
  1645     (aNumber class == SmallInteger) ifTrue:[
  1646         otherSign := aNumber sign.
  1646 	otherSign := aNumber sign.
  1647 
  1647 
  1648         (sign > 0) ifTrue:[
  1648 	(sign > 0) ifTrue:[
  1649             "I am positive"
  1649 	    "I am positive"
  1650             ^ false "aNumber is <= 0"
  1650 	    ^ false "aNumber is <= 0"
  1651         ].
  1651 	].
  1652         (sign == 0) ifTrue:[
  1652 	(sign == 0) ifTrue:[
  1653             (otherSign > 0) ifTrue:[^ true].
  1653 	    (otherSign > 0) ifTrue:[^ true].
  1654             ^ false
  1654 	    ^ false
  1655         ].
  1655 	].
  1656         "I am negative"
  1656 	"I am negative"
  1657         ^ true
  1657 	^ true
  1658     ].
  1658     ].
  1659 
  1659 
  1660     ^ aNumber lessFromInteger:self
  1660     ^ aNumber lessFromInteger:self
  1661 
  1661 
  1662     "Modified: / 31.7.2002 / 10:08:19 / cg"
  1662     "Modified: / 31.7.2002 / 10:08:19 / cg"
  1667      as the receiver, false otherwise"
  1667      as the receiver, false otherwise"
  1668 
  1668 
  1669     "/ speed up compare to 0
  1669     "/ speed up compare to 0
  1670 
  1670 
  1671     (aNumber == 0) ifTrue:[
  1671     (aNumber == 0) ifTrue:[
  1672         ^ sign == 0
  1672 	^ sign == 0
  1673     ].
  1673     ].
  1674 
  1674 
  1675     (aNumber class == self class) ifFalse:[
  1675     (aNumber class == self class) ifFalse:[
  1676         "/
  1676 	"/
  1677         "/ here, we depend on the fact, that largeinteger
  1677 	"/ here, we depend on the fact, that largeinteger
  1678         "/ results are always converted to smallInts, if possible.
  1678 	"/ results are always converted to smallInts, if possible.
  1679         "/ therefore, a largeInt in the smallInt range is not allowed (possible)
  1679 	"/ therefore, a largeInt in the smallInt range is not allowed (possible)
  1680         "/
  1680 	"/
  1681         aNumber class == SmallInteger ifTrue:[^ false ].
  1681 	aNumber class == SmallInteger ifTrue:[^ false ].
  1682         ^ aNumber equalFromInteger:self
  1682 	^ aNumber equalFromInteger:self
  1683     ].
  1683     ].
  1684 
  1684 
  1685     (aNumber sign == sign) ifFalse:[^ false].
  1685     (aNumber sign == sign) ifFalse:[^ false].
  1686     ^ digitByteArray = aNumber digitBytes "/ ^ self absEq:aNumber
  1686     ^ digitByteArray = aNumber digitBytes "/ ^ self absEq:aNumber
  1687 
  1687 
  1723 
  1723 
  1724     h := self bitAnd:16r3FFFFFFF.
  1724     h := self bitAnd:16r3FFFFFFF.
  1725 
  1725 
  1726     l := digitByteArray size.
  1726     l := digitByteArray size.
  1727     l >= 8 ifTrue:[
  1727     l >= 8 ifTrue:[
  1728         h := h bitXor:(digitByteArray at:l).        
  1728 	h := h bitXor:(digitByteArray at:l).
  1729         h := h bitXor:((digitByteArray at:l-1) bitShift:8).        
  1729 	h := h bitXor:((digitByteArray at:l-1) bitShift:8).
  1730         h := h bitXor:((digitByteArray at:l-2) bitShift:16).        
  1730 	h := h bitXor:((digitByteArray at:l-2) bitShift:16).
  1731         h := h bitXor:((digitByteArray at:l-3) bitShift:22).        
  1731 	h := h bitXor:((digitByteArray at:l-3) bitShift:22).
  1732         l >= 12 ifTrue:[
  1732 	l >= 12 ifTrue:[
  1733             m := l // 2.
  1733 	    m := l // 2.
  1734             h := h bitXor:(digitByteArray at:m-1).        
  1734 	    h := h bitXor:(digitByteArray at:m-1).
  1735             h := h bitXor:((digitByteArray at:m) bitShift:8).        
  1735 	    h := h bitXor:((digitByteArray at:m) bitShift:8).
  1736             h := h bitXor:((digitByteArray at:m+1) bitShift:16).        
  1736 	    h := h bitXor:((digitByteArray at:m+1) bitShift:16).
  1737             h := h bitXor:((digitByteArray at:m+2) bitShift:22).        
  1737 	    h := h bitXor:((digitByteArray at:m+2) bitShift:22).
  1738         ].
  1738 	].
  1739         ^ h
  1739 	^ h
  1740     ].
  1740     ].
  1741     ^ (h bitShift:3) + l
  1741     ^ (h bitShift:3) + l
  1742 
  1742 
  1743     "
  1743     "
  1744      16r80000000 hash 
  1744      16r80000000 hash
  1745      16r80000008 hash 
  1745      16r80000008 hash
  1746      16r8000000000008 hash  
  1746      16r8000000000008 hash
  1747     "
  1747     "
  1748 ! !
  1748 ! !
  1749 
  1749 
  1750 !LargeInteger methodsFor:'double dispatching'!
  1750 !LargeInteger methodsFor:'double dispatching'!
  1751 
  1751 
  1752 differenceFromInteger:anInteger
  1752 differenceFromInteger:anInteger
  1753     "sent, when anInteger does not know how to subtract the receiver.
  1753     "sent, when anInteger does not know how to subtract the receiver.
  1754      Return the result of 'anInteger - self'. The argument must be a SmallInteger."
  1754      Return the result of 'anInteger - self'. The argument must be a SmallInteger."
  1755 
  1755 
  1756     anInteger > 0 ifTrue:[
  1756     anInteger > 0 ifTrue:[
  1757         sign > 0 ifTrue:[
  1757 	sign > 0 ifTrue:[
  1758             ^ self absFastMinus:anInteger sign:-1
  1758 	    ^ self absFastMinus:anInteger sign:-1
  1759         ].
  1759 	].
  1760         ^ self absFastPlus:anInteger sign:1
  1760 	^ self absFastPlus:anInteger sign:1
  1761     ].
  1761     ].
  1762     anInteger == 0 ifTrue:[
  1762     anInteger == 0 ifTrue:[
  1763         ^ self negated
  1763 	^ self negated
  1764     ].
  1764     ].
  1765     sign > 0 ifTrue:[
  1765     sign > 0 ifTrue:[
  1766         ^ self absFastPlus:anInteger negated sign:-1
  1766 	^ self absFastPlus:anInteger negated sign:-1
  1767     ].
  1767     ].
  1768 
  1768 
  1769     self > anInteger ifTrue:[
  1769     self > anInteger ifTrue:[
  1770         ^ self absFastMinus:anInteger asLargeInteger sign:-1    
  1770 	^ self absFastMinus:anInteger asLargeInteger sign:-1
  1771     ] ifFalse:[
  1771     ] ifFalse:[
  1772         ^ anInteger asLargeInteger absFastMinus:self sign:-1    
  1772 	^ anInteger asLargeInteger absFastMinus:self sign:-1
  1773     ].
  1773     ].
  1774 
  1774 
  1775     "
  1775     "
  1776      12345678901234567890
  1776      12345678901234567890
  1777      -12345678901234567890
  1777      -12345678901234567890
  1793     "/ results are always converted to smallInts, if possible.
  1793     "/ results are always converted to smallInts, if possible.
  1794     "/ therefore, a largeInt in the smallInt range is not allowed (possible)
  1794     "/ therefore, a largeInt in the smallInt range is not allowed (possible)
  1795     "/
  1795     "/
  1796     anInteger class == SmallInteger ifTrue:[^ false ].
  1796     anInteger class == SmallInteger ifTrue:[^ false ].
  1797     anInteger class == self class ifFalse:[
  1797     anInteger class == self class ifFalse:[
  1798         ^ super equalFromInteger:anInteger
  1798 	^ super equalFromInteger:anInteger
  1799     ].
  1799     ].
  1800     (anInteger sign == sign) ifFalse:[^ false].
  1800     (anInteger sign == sign) ifFalse:[^ false].
  1801     ^ self absEq:anInteger
  1801     ^ self absEq:anInteger
  1802 !
  1802 !
  1803 
  1803 
  1810     "/ here, we depend on the fact, that largeinteger
  1810     "/ here, we depend on the fact, that largeinteger
  1811     "/ results are always converted to smallInts, if possible.
  1811     "/ results are always converted to smallInts, if possible.
  1812     "/ therefore, a largeInt in the smallInt range is not allowed (possible)
  1812     "/ therefore, a largeInt in the smallInt range is not allowed (possible)
  1813     "/
  1813     "/
  1814     (anInteger class == SmallInteger) ifTrue:[
  1814     (anInteger class == SmallInteger) ifTrue:[
  1815         otherSign := anInteger sign.
  1815 	otherSign := anInteger sign.
  1816 
  1816 
  1817         (sign > 0) ifTrue:[
  1817 	(sign > 0) ifTrue:[
  1818             "I am positive"
  1818 	    "I am positive"
  1819             ^ true "aNumber is <= 0"
  1819 	    ^ true "aNumber is <= 0"
  1820         ].
  1820 	].
  1821         "I am negative"
  1821 	"I am negative"
  1822         ^ false
  1822 	^ false
  1823     ].
  1823     ].
  1824     ^ super lessFromInteger:anInteger
  1824     ^ super lessFromInteger:anInteger
  1825 !
  1825 !
  1826 
  1826 
  1827 productFromInteger:anInteger
  1827 productFromInteger:anInteger
  2259 
  2259 
  2260 %{  /* NOCONTEXT */
  2260 %{  /* NOCONTEXT */
  2261     OBJ _digitByteArray = __INST(digitByteArray);
  2261     OBJ _digitByteArray = __INST(digitByteArray);
  2262 
  2262 
  2263     if (__isLargeInteger(aLargeInteger)) {
  2263     if (__isLargeInteger(aLargeInteger)) {
  2264         OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
  2264 	OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
  2265 
  2265 
  2266         if (__isByteArray(_digitByteArray)
  2266 	if (__isByteArray(_digitByteArray)
  2267          && __isByteArray(_otherDigitByteArray)) {
  2267 	 && __isByteArray(_otherDigitByteArray)) {
  2268             INT _myLen = __byteArraySize(_digitByteArray);
  2268 	    INT _myLen = __byteArraySize(_digitByteArray);
  2269             INT _otherLen = __byteArraySize(_otherDigitByteArray);
  2269 	    INT _otherLen = __byteArraySize(_otherDigitByteArray);
  2270 
  2270 
  2271             unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
  2271 	    unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
  2272             unsigned char *_myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
  2272 	    unsigned char *_myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
  2273 
  2273 
  2274             if (_myLen == _otherLen) {
  2274 	    if (_myLen == _otherLen) {
  2275 tryAgain:
  2275 tryAgain:
  2276                 while (_myLen >= (sizeof(INT))) {
  2276 		while (_myLen >= (sizeof(INT)*4)) {
  2277                     if ( *(unsigned INT *)_myDigits != *(unsigned INT *)_otherDigits) {
  2277 		    if ( (unsigned INT *)_myDigits[0] != (unsigned INT *)_otherDigits[0]) {
  2278                         RETURN(false);
  2278 			RETURN(false);
  2279                     }
  2279 		    }
  2280                     _myDigits += sizeof(INT);
  2280 		    if ( (unsigned INT *)_myDigits[1] != (unsigned INT *)_otherDigits[1]) {
  2281                     _otherDigits += sizeof(INT);
  2281 			RETURN(false);
  2282                     _myLen -= sizeof(INT);
  2282 		    }
  2283                 }
  2283 		    if ( (unsigned INT *)_myDigits[2] != (unsigned INT *)_otherDigits[2]) {
  2284                 while (_myLen > 0) {
  2284 			RETURN(false);
  2285                     if ( *_myDigits != *_otherDigits) {
  2285 		    }
  2286                         RETURN(false);
  2286 		    if ( (unsigned INT *)_myDigits[3] != (unsigned INT *)_otherDigits[3]) {
  2287                     }
  2287 			RETURN(false);
  2288                     _myDigits++;
  2288 		    }
  2289                     _otherDigits++;
  2289 		    _myDigits += sizeof(INT)*4;
  2290                     _myLen--;
  2290 		    _otherDigits += sizeof(INT)*4;
  2291                 }
  2291 		    _myLen -= sizeof(INT)*4;
  2292                 RETURN(true);
  2292 		}
  2293             }
  2293 		while (_myLen >= (sizeof(INT))) {
  2294             /* care for unnormalized ints */
  2294 		    if ( *(unsigned INT *)_myDigits != *(unsigned INT *)_otherDigits) {
  2295             while ((_myLen > 0) && (_myDigits[_myLen-1] == 0)) _myLen--;
  2295 			RETURN(false);
  2296             while ((_otherLen > 0) && (_otherDigits[_otherLen-1] == 0)) _otherLen--;
  2296 		    }
  2297             if (_myLen == _otherLen) goto tryAgain;
  2297 		    _myDigits += sizeof(INT);
  2298             RETURN(false);
  2298 		    _otherDigits += sizeof(INT);
  2299         }
  2299 		    _myLen -= sizeof(INT);
       
  2300 		}
       
  2301 		while (_myLen > 0) {
       
  2302 		    if ( *_myDigits != *_otherDigits) {
       
  2303 			RETURN(false);
       
  2304 		    }
       
  2305 		    _myDigits++;
       
  2306 		    _otherDigits++;
       
  2307 		    _myLen--;
       
  2308 		}
       
  2309 		RETURN(true);
       
  2310 	    }
       
  2311 	    /* care for unnormalized ints */
       
  2312 	    while ((_myLen > 0) && (_myDigits[_myLen-1] == 0)) _myLen--;
       
  2313 	    while ((_otherLen > 0) && (_otherDigits[_otherLen-1] == 0)) _otherLen--;
       
  2314 	    if (_myLen == _otherLen) goto tryAgain;
       
  2315 	    RETURN(false);
       
  2316 	}
  2300     }
  2317     }
  2301 %}.
  2318 %}.
  2302 
  2319 
  2303     len1 := digitByteArray size.
  2320     len1 := digitByteArray size.
  2304     otherDigitByteArray := aLargeInteger digitBytes.
  2321     otherDigitByteArray := aLargeInteger digitBytes.
  2308     "/ when properly normalized;
  2325     "/ when properly normalized;
  2309     "/ but we are tolerant here, to allow for unnormalized
  2326     "/ but we are tolerant here, to allow for unnormalized
  2310     "/ numbers to be compared ...
  2327     "/ numbers to be compared ...
  2311 
  2328 
  2312     [(digitByteArray basicAt:len1) == 0] whileTrue:[
  2329     [(digitByteArray basicAt:len1) == 0] whileTrue:[
  2313         len1 := len1 - 1
  2330 	len1 := len1 - 1
  2314     ].
  2331     ].
  2315     [(otherDigitByteArray basicAt:len2) == 0] whileTrue:[
  2332     [(otherDigitByteArray basicAt:len2) == 0] whileTrue:[
  2316         len2 := len2 - 1
  2333 	len2 := len2 - 1
  2317     ].
  2334     ].
  2318     (len1 ~~ len2) ifTrue:[^ false].
  2335     (len1 ~~ len2) ifTrue:[^ false].
  2319     [len1 > 0] whileTrue:[
  2336     [len1 > 0] whileTrue:[
  2320         d1 := digitByteArray basicAt:len1.
  2337 	d1 := digitByteArray basicAt:len1.
  2321         d2 := otherDigitByteArray basicAt:len1.
  2338 	d2 := otherDigitByteArray basicAt:len1.
  2322         (d1 ~~ d2) ifTrue:[^ false].
  2339 	(d1 ~~ d2) ifTrue:[^ false].
  2323         len1 := len1 - 1
  2340 	len1 := len1 - 1
  2324     ].
  2341     ].
  2325     ^ true
  2342     ^ true
  2326 
  2343 
  2327     "Modified: / 8.5.1999 / 18:37:02 / cg"
  2344     "Modified: / 8.5.1999 / 18:37:02 / cg"
  2328 !
  2345 !
  2337      count    "{ Class: SmallInteger }"
  2354      count    "{ Class: SmallInteger }"
  2338      newDigitByteArray result
  2355      newDigitByteArray result
  2339      ok|
  2356      ok|
  2340 
  2357 
  2341     aPositiveSmallInteger == 0 ifTrue:[
  2358     aPositiveSmallInteger == 0 ifTrue:[
  2342         ^ ZeroDivide raiseRequestWith:thisContext
  2359 	^ ZeroDivide raiseRequestWith:thisContext
  2343     ].
  2360     ].
  2344 
  2361 
  2345 "This cannot happen (if always normalized)
  2362 "This cannot happen (if always normalized)
  2346     self < aPositiveSmallInteger ifTrue:[
  2363     self < aPositiveSmallInteger ifTrue:[
  2347         ^ Array with:0 with:self
  2364 	^ Array with:0 with:self
  2348     ].
  2365     ].
  2349 "
  2366 "
  2350     count := digitByteArray size.
  2367     count := digitByteArray size.
  2351     result := self class basicNew numberOfDigits:count.
  2368     result := self class basicNew numberOfDigits:count.
  2352     newDigitByteArray := result digitBytes.
  2369     newDigitByteArray := result digitBytes.
  2357     __digits = __INST(digitByteArray);
  2374     __digits = __INST(digitByteArray);
  2358 
  2375 
  2359     if (__isByteArray(__digits)
  2376     if (__isByteArray(__digits)
  2360      && __isByteArray(newDigitByteArray)
  2377      && __isByteArray(newDigitByteArray)
  2361      && __bothSmallInteger(count, aPositiveSmallInteger)) {
  2378      && __bothSmallInteger(count, aPositiveSmallInteger)) {
  2362         unsigned INT rest = 0;
  2379 	unsigned INT rest = 0;
  2363         int index = __intVal(count);
  2380 	int index = __intVal(count);
  2364         int index0;
  2381 	int index0;
  2365         unsigned INT divisor = __intVal(aPositiveSmallInteger);
  2382 	unsigned INT divisor = __intVal(aPositiveSmallInteger);
  2366         unsigned char *digitBytes = __ByteArrayInstPtr(__digits)->ba_element;
  2383 	unsigned char *digitBytes = __ByteArrayInstPtr(__digits)->ba_element;
  2367         unsigned char *resultBytes = __ByteArrayInstPtr(newDigitByteArray)->ba_element;
  2384 	unsigned char *resultBytes = __ByteArrayInstPtr(newDigitByteArray)->ba_element;
  2368 
  2385 
  2369         index0 = index - 1;
  2386 	index0 = index - 1;
  2370 
  2387 
  2371         /*
  2388 	/*
  2372          * divide short-wise
  2389 	 * divide short-wise
  2373          */
  2390 	 */
  2374         if (divisor <= 0xFFFF) {
  2391 	if (divisor <= 0xFFFF) {
  2375             if ((index & 1) == 0) { /* even number of bytes */
  2392 	    if ((index & 1) == 0) { /* even number of bytes */
  2376                 while (index > 1) {
  2393 		while (index > 1) {
  2377                     unsigned INT t;
  2394 		    unsigned INT t;
  2378                     unsigned INT div;
  2395 		    unsigned INT div;
  2379 
  2396 
  2380                     index -= 2;
  2397 		    index -= 2;
  2381 #if defined(__LSBFIRST__)
  2398 #if defined(__LSBFIRST__)
  2382                     t = *((unsigned short *)(&digitBytes[index]));
  2399 		    t = *((unsigned short *)(&digitBytes[index]));
  2383 #else
  2400 #else
  2384                     t = digitBytes[index+1];
  2401 		    t = digitBytes[index+1];
  2385                     t = (t << 8) | digitBytes[index];
  2402 		    t = (t << 8) | digitBytes[index];
  2386 #endif
  2403 #endif
  2387                     t = t | (rest << 16);
  2404 		    t = t | (rest << 16);
  2388                     div = t / divisor;
  2405 		    div = t / divisor;
  2389                     rest = t % divisor;
  2406 		    rest = t % divisor;
  2390 #if defined(__LSBFIRST__)
  2407 #if defined(__LSBFIRST__)
  2391                     *((unsigned short *)(&resultBytes[index])) = (div & 0xFFFF);
  2408 		    *((unsigned short *)(&resultBytes[index])) = (div & 0xFFFF);
  2392 #else
  2409 #else
  2393                     resultBytes[index+1] = div >> 8;
  2410 		    resultBytes[index+1] = div >> 8;
  2394                     resultBytes[index] = div /* & 0xFF */;
  2411 		    resultBytes[index] = div /* & 0xFF */;
  2395 #endif
  2412 #endif
  2396                 }
  2413 		}
  2397             }
  2414 	    }
  2398         }
  2415 	}
  2399         while (index > 0) {
  2416 	while (index > 0) {
  2400             unsigned INT t;
  2417 	    unsigned INT t;
  2401 
  2418 
  2402             index--;
  2419 	    index--;
  2403             t = digitBytes[index];
  2420 	    t = digitBytes[index];
  2404             t = t | (rest << 8);
  2421 	    t = t | (rest << 8);
  2405             resultBytes[index] = t / divisor;
  2422 	    resultBytes[index] = t / divisor;
  2406             rest = t % divisor;
  2423 	    rest = t % divisor;
  2407         }
  2424 	}
  2408         prevRest = __mkSmallInteger(rest);
  2425 	prevRest = __mkSmallInteger(rest);
  2409 
  2426 
  2410         /*
  2427 	/*
  2411          * no need to normalize ?
  2428 	 * no need to normalize ?
  2412          */
  2429 	 */
  2413         index = index0;
  2430 	index = index0;
  2414         while ((index >= sizeof(INT)) && (resultBytes[index]==0)) {
  2431 	while ((index >= sizeof(INT)) && (resultBytes[index]==0)) {
  2415             index--;
  2432 	    index--;
  2416         }
  2433 	}
  2417 
  2434 
  2418         if (index == index0) {
  2435 	if (index == index0) {
  2419             if (index > sizeof(INT)) {
  2436 	    if (index > sizeof(INT)) {
  2420                 RETURN ( __ARRAY_WITH2(result, prevRest));
  2437 		RETURN ( __ARRAY_WITH2(result, prevRest));
  2421             }
  2438 	    }
  2422             if ((index == sizeof(INT))
  2439 	    if ((index == sizeof(INT))
  2423             && resultBytes[index0] >= 0x40) {
  2440 	    && resultBytes[index0] >= 0x40) {
  2424                 RETURN ( __ARRAY_WITH2(result, prevRest));
  2441 		RETURN ( __ARRAY_WITH2(result, prevRest));
  2425             }
  2442 	    }
  2426         }
  2443 	}
  2427 
  2444 
  2428         /*
  2445 	/*
  2429          * must compress
  2446 	 * must compress
  2430          */
  2447 	 */
  2431         ok = true;
  2448 	ok = true;
  2432     }
  2449     }
  2433 %}.
  2450 %}.
  2434     "
  2451     "
  2435      slow code - not normally reached
  2452      slow code - not normally reached
  2436      (could also do a primitiveFailure here)
  2453      (could also do a primitiveFailure here)
  2437     "
  2454     "
  2438     ok ifFalse:[
  2455     ok ifFalse:[
  2439         ^ self absDivMod:(LargeInteger value:aPositiveSmallInteger).
  2456 	^ self absDivMod:(LargeInteger value:aPositiveSmallInteger).
  2440     ].
  2457     ].
  2441 
  2458 
  2442     ^ Array with:(result compressed) with:prevRest
  2459     ^ Array with:(result compressed) with:prevRest
  2443 
  2460 
  2444     "
  2461     "
  2987 
  3004 
  2988 %{  /* NOCONTEXT */
  3005 %{  /* NOCONTEXT */
  2989 #if defined(__LSBFIRST__)
  3006 #if defined(__LSBFIRST__)
  2990     if (__isByteArray(__INST(digitByteArray))
  3007     if (__isByteArray(__INST(digitByteArray))
  2991      && __isLargeInteger(aLargeInteger)) {
  3008      && __isLargeInteger(aLargeInteger)) {
  2992         OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
  3009 	OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
  2993 
  3010 
  2994         if (__isByteArray(_otherDigitByteArray)) {
  3011 	if (__isByteArray(_otherDigitByteArray)) {
  2995             unsigned char *_myDigits = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
  3012 	    unsigned char *_myDigits = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
  2996             unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
  3013 	    unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
  2997             INT _myLen = __byteArraySize(__INST(digitByteArray));
  3014 	    INT _myLen = __byteArraySize(__INST(digitByteArray));
  2998 
  3015 
  2999             if (_myLen == __POINTER_SIZE__) {
  3016 	    if (_myLen == __POINTER_SIZE__) {
  3000                 INT _otherLen = __byteArraySize(_otherDigitByteArray);
  3017 		INT _otherLen = __byteArraySize(_otherDigitByteArray);
  3001 
  3018 
  3002                 if (_otherLen == __POINTER_SIZE__) {
  3019 		if (_otherLen == __POINTER_SIZE__) {
  3003                     unsigned INT _myVal = *((unsigned INT *)_myDigits);
  3020 		    unsigned INT _myVal = *((unsigned INT *)_myDigits);
  3004                     unsigned INT _otherVal = *((unsigned INT *)_otherDigits);
  3021 		    unsigned INT _otherVal = *((unsigned INT *)_otherDigits);
  3005                     RETURN( (_myVal < _otherVal) ? true : false );
  3022 		    RETURN( (_myVal < _otherVal) ? true : false );
  3006                 }
  3023 		}
  3007             }
  3024 	    }
  3008 # if defined(UINT64) && (__POINTER_SIZE__ != 8)
  3025 # if defined(UINT64) && (__POINTER_SIZE__ != 8)
  3009             if (_myLen == __POINTER_SIZE__) {
  3026 	    if (_myLen == __POINTER_SIZE__) {
  3010                 INT _otherLen = __byteArraySize(_otherDigitByteArray);
  3027 		INT _otherLen = __byteArraySize(_otherDigitByteArray);
  3011 
  3028 
  3012                 if (_otherLen <= 8) {
  3029 		if (_otherLen <= 8) {
  3013                     UINT64 _myVal = (UINT64)(*((UINT *)_myDigits));
  3030 		    UINT64 _myVal = (UINT64)(*((UINT *)_myDigits));
  3014                     UINT64 _otherVal = *((UINT64 *)_otherDigits);
  3031 		    UINT64 _otherVal = *((UINT64 *)_otherDigits);
  3015                     RETURN( (_myVal < _otherVal) ? true : false );
  3032 		    RETURN( (_myVal < _otherVal) ? true : false );
  3016                 }
  3033 		}
  3017             } else {
  3034 	    } else {
  3018                 if (_myLen <= 8) {
  3035 		if (_myLen <= 8) {
  3019                     INT _otherLen = __byteArraySize(_otherDigitByteArray);
  3036 		    INT _otherLen = __byteArraySize(_otherDigitByteArray);
  3020 
  3037 
  3021                     if (_otherLen <= 8) {
  3038 		    if (_otherLen <= 8) {
  3022                         UINT64 _myVal = (*((UINT64 *)_myDigits));
  3039 			UINT64 _myVal = (*((UINT64 *)_myDigits));
  3023                         UINT64 _otherVal = *((UINT64 *)_otherDigits);
  3040 			UINT64 _otherVal = *((UINT64 *)_otherDigits);
  3024                         RETURN( (_myVal < _otherVal) ? true : false );
  3041 			RETURN( (_myVal < _otherVal) ? true : false );
  3025                     }
  3042 		    }
  3026                     if (_otherLen == __POINTER_SIZE__) {
  3043 		    if (_otherLen == __POINTER_SIZE__) {
  3027                         UINT64 _myVal = (*((UINT64 *)_myDigits));
  3044 			UINT64 _myVal = (*((UINT64 *)_myDigits));
  3028                         UINT64 _otherVal = (UINT64) *((UINT *)_otherDigits);
  3045 			UINT64 _otherVal = (UINT64) *((UINT *)_otherDigits);
  3029                         RETURN( (_myVal < _otherVal) ? true : false );
  3046 			RETURN( (_myVal < _otherVal) ? true : false );
  3030                     }
  3047 		    }
  3031                 }
  3048 		}
  3032             }
  3049 	    }
  3033 # endif /* UINT64 */
  3050 # endif /* UINT64 */
  3034         }
  3051 	}
  3035     }
  3052     }
  3036 #endif /* LSBFIRST */
  3053 #endif /* LSBFIRST */
  3037 %}.
  3054 %}.
  3038 
  3055 
  3039     myLen := digitByteArray size.
  3056     myLen := digitByteArray size.
  3044     "/ when properly normalized;
  3061     "/ when properly normalized;
  3045     "/ but we are tolerant here, to allow for unnormalized
  3062     "/ but we are tolerant here, to allow for unnormalized
  3046     "/ numbers to be compared ...
  3063     "/ numbers to be compared ...
  3047 
  3064 
  3048     [myLen > 0 and:[(digitByteArray basicAt:myLen) == 0]] whileTrue:[
  3065     [myLen > 0 and:[(digitByteArray basicAt:myLen) == 0]] whileTrue:[
  3049         myLen := myLen - 1
  3066 	myLen := myLen - 1
  3050     ].
  3067     ].
  3051     [otherLen > 0 and:[(otherDigitByteArray basicAt:otherLen) == 0]] whileTrue:[
  3068     [otherLen > 0 and:[(otherDigitByteArray basicAt:otherLen) == 0]] whileTrue:[
  3052         otherLen := otherLen - 1
  3069 	otherLen := otherLen - 1
  3053     ].
  3070     ].
  3054     (myLen < otherLen) ifTrue:[^ true].
  3071     (myLen < otherLen) ifTrue:[^ true].
  3055     (myLen > otherLen) ifTrue:[^ false].
  3072     (myLen > otherLen) ifTrue:[^ false].
  3056 
  3073 
  3057     [myLen > 0] whileTrue:[
  3074     [myLen > 0] whileTrue:[
  3058         d1 := digitByteArray basicAt:myLen.
  3075 	d1 := digitByteArray basicAt:myLen.
  3059         d2 := otherDigitByteArray basicAt:myLen.
  3076 	d2 := otherDigitByteArray basicAt:myLen.
  3060         d1 == d2 ifFalse:[
  3077 	d1 == d2 ifFalse:[
  3061             (d1 < d2) ifTrue:[^ true].
  3078 	    (d1 < d2) ifTrue:[^ true].
  3062             ^ false
  3079 	    ^ false
  3063         ].
  3080 	].
  3064         myLen := myLen - 1
  3081 	myLen := myLen - 1
  3065     ].
  3082     ].
  3066     ^ false
  3083     ^ false
  3067 
  3084 
  3068     "
  3085     "
  3069      |a b|
  3086      |a b|
  3078 
  3095 
  3079      a := 16rFEFFFFFF.
  3096      a := 16rFEFFFFFF.
  3080      b := 16rFFFFFFFF.
  3097      b := 16rFFFFFFFF.
  3081      Time millisecondsToRun:[
  3098      Time millisecondsToRun:[
  3082        10000000 timesRepeat:[ a absLess_n:b ]
  3099        10000000 timesRepeat:[ a absLess_n:b ]
  3083      ] 686 655 702 702  
  3100      ] 686 655 702 702
  3084 
  3101 
  3085      16rEFFFFFFF  absLess_n: 16rFFFFFFFF
  3102      16rEFFFFFFF  absLess_n: 16rFFFFFFFF
  3086      16rEFFFFFFF  absLess: 16rFFFFFFFF 
  3103      16rEFFFFFFF  absLess: 16rFFFFFFFF
  3087     "
  3104     "
  3088 
  3105 
  3089     "Modified: / 3.5.1999 / 08:06:28 / stefan"
  3106     "Modified: / 3.5.1999 / 08:06:28 / stefan"
  3090     "Modified: / 8.5.1999 / 18:37:11 / cg"
  3107     "Modified: / 8.5.1999 / 18:37:11 / cg"
  3091 !
  3108 !
  3102 
  3119 
  3103 %{  /* NOCONTEXT */
  3120 %{  /* NOCONTEXT */
  3104 #if defined(__LSBFIRST__)
  3121 #if defined(__LSBFIRST__)
  3105     if (__isByteArray(__INST(digitByteArray))
  3122     if (__isByteArray(__INST(digitByteArray))
  3106      && __isLargeInteger(aLargeInteger)) {
  3123      && __isLargeInteger(aLargeInteger)) {
  3107         OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
  3124 	OBJ _otherDigitByteArray = __LargeIntegerInstPtr(aLargeInteger)->l_digits;
  3108 
  3125 
  3109         if (__isByteArray(_otherDigitByteArray)) {
  3126 	if (__isByteArray(_otherDigitByteArray)) {
  3110             unsigned char *_myDigits = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
  3127 	    unsigned char *_myDigits = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element;
  3111             unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
  3128 	    unsigned char *_otherDigits = __ByteArrayInstPtr(_otherDigitByteArray)->ba_element;
  3112             INT _myLen = __byteArraySize(__INST(digitByteArray));
  3129 	    INT _myLen = __byteArraySize(__INST(digitByteArray));
  3113 
  3130 
  3114             if (_myLen == __POINTER_SIZE__) {
  3131 	    if (_myLen == __POINTER_SIZE__) {
  3115                 INT _otherLen = __byteArraySize(_otherDigitByteArray);
  3132 		INT _otherLen = __byteArraySize(_otherDigitByteArray);
  3116 
  3133 
  3117                 if (_otherLen == __POINTER_SIZE__) {
  3134 		if (_otherLen == __POINTER_SIZE__) {
  3118                     unsigned INT _myVal = *((unsigned INT *)_myDigits);
  3135 		    unsigned INT _myVal = *((unsigned INT *)_myDigits);
  3119                     unsigned INT _otherVal = *((unsigned INT *)_otherDigits);
  3136 		    unsigned INT _otherVal = *((unsigned INT *)_otherDigits);
  3120                     RETURN( (_myVal <= _otherVal) ? true : false );
  3137 		    RETURN( (_myVal <= _otherVal) ? true : false );
  3121                 }
  3138 		}
  3122             }
  3139 	    }
  3123 # if defined(UINT64) && (__POINTER_SIZE__ != 8)
  3140 # if defined(UINT64) && (__POINTER_SIZE__ != 8)
  3124             if (_myLen == __POINTER_SIZE__) {
  3141 	    if (_myLen == __POINTER_SIZE__) {
  3125                 INT _otherLen = __byteArraySize(_otherDigitByteArray);
  3142 		INT _otherLen = __byteArraySize(_otherDigitByteArray);
  3126 
  3143 
  3127                 if (_otherLen <= 8) {
  3144 		if (_otherLen <= 8) {
  3128                     UINT64 _myVal = (UINT64)(*((UINT *)_myDigits));
  3145 		    UINT64 _myVal = (UINT64)(*((UINT *)_myDigits));
  3129                     UINT64 _otherVal = *((UINT64 *)_otherDigits);
  3146 		    UINT64 _otherVal = *((UINT64 *)_otherDigits);
  3130                     RETURN( (_myVal <= _otherVal) ? true : false );
  3147 		    RETURN( (_myVal <= _otherVal) ? true : false );
  3131                 }
  3148 		}
  3132             } else {
  3149 	    } else {
  3133                 if (_myLen <= 8) {
  3150 		if (_myLen <= 8) {
  3134                     INT _otherLen = __byteArraySize(_otherDigitByteArray);
  3151 		    INT _otherLen = __byteArraySize(_otherDigitByteArray);
  3135 
  3152 
  3136                     if (_otherLen <= 8) {
  3153 		    if (_otherLen <= 8) {
  3137                         UINT64 _myVal = (*((UINT64 *)_myDigits));
  3154 			UINT64 _myVal = (*((UINT64 *)_myDigits));
  3138                         UINT64 _otherVal = *((UINT64 *)_otherDigits);
  3155 			UINT64 _otherVal = *((UINT64 *)_otherDigits);
  3139                         RETURN( (_myVal <= _otherVal) ? true : false );
  3156 			RETURN( (_myVal <= _otherVal) ? true : false );
  3140                     }
  3157 		    }
  3141                     if (_otherLen == __POINTER_SIZE__) {
  3158 		    if (_otherLen == __POINTER_SIZE__) {
  3142                         UINT64 _myVal = (*((UINT64 *)_myDigits));
  3159 			UINT64 _myVal = (*((UINT64 *)_myDigits));
  3143                         UINT64 _otherVal = (UINT64) *((UINT *)_otherDigits);
  3160 			UINT64 _otherVal = (UINT64) *((UINT *)_otherDigits);
  3144                         RETURN( (_myVal <= _otherVal) ? true : false );
  3161 			RETURN( (_myVal <= _otherVal) ? true : false );
  3145                     }
  3162 		    }
  3146                 }
  3163 		}
  3147             }
  3164 	    }
  3148 # endif /* UINT64 */
  3165 # endif /* UINT64 */
  3149         }
  3166 	}
  3150     }
  3167     }
  3151 #endif /* LSBFIRST */
  3168 #endif /* LSBFIRST */
  3152 %}.
  3169 %}.
  3153 
  3170 
  3154     myLen := digitByteArray size.
  3171     myLen := digitByteArray size.
  3159     "/ when properly normalized;
  3176     "/ when properly normalized;
  3160     "/ but we are tolerant here, to allow for unnormalized
  3177     "/ but we are tolerant here, to allow for unnormalized
  3161     "/ numbers to be compared ...
  3178     "/ numbers to be compared ...
  3162 
  3179 
  3163     [(digitByteArray basicAt:myLen) == 0] whileTrue:[
  3180     [(digitByteArray basicAt:myLen) == 0] whileTrue:[
  3164         myLen := myLen - 1
  3181 	myLen := myLen - 1
  3165     ].
  3182     ].
  3166     [(otherDigitByteArray basicAt:otherLen) == 0] whileTrue:[
  3183     [(otherDigitByteArray basicAt:otherLen) == 0] whileTrue:[
  3167         otherLen := otherLen - 1
  3184 	otherLen := otherLen - 1
  3168     ].
  3185     ].
  3169     (myLen < otherLen) ifTrue:[^ true].
  3186     (myLen < otherLen) ifTrue:[^ true].
  3170     (myLen > otherLen) ifTrue:[^ false].
  3187     (myLen > otherLen) ifTrue:[^ false].
  3171 
  3188 
  3172     [myLen > 0] whileTrue:[
  3189     [myLen > 0] whileTrue:[
  3173         d1 := digitByteArray basicAt:myLen.
  3190 	d1 := digitByteArray basicAt:myLen.
  3174         d2 := otherDigitByteArray basicAt:myLen.
  3191 	d2 := otherDigitByteArray basicAt:myLen.
  3175         d1 == d2 ifFalse:[
  3192 	d1 == d2 ifFalse:[
  3176             (d1 < d2) ifTrue:[^ true].
  3193 	    (d1 < d2) ifTrue:[^ true].
  3177             ^ false.
  3194 	    ^ false.
  3178         ].
  3195 	].
  3179         myLen := myLen - 1
  3196 	myLen := myLen - 1
  3180     ].
  3197     ].
  3181     ^ true
  3198     ^ true
  3182 
  3199 
  3183     "Created: / 13.2.1998 / 12:19:45 / stefan"
  3200     "Created: / 13.2.1998 / 12:19:45 / stefan"
  3184     "Modified: / 30.4.1999 / 12:46:31 / stefan"
  3201     "Modified: / 30.4.1999 / 12:46:31 / stefan"
  3206     len1 := digitByteArray size.
  3223     len1 := digitByteArray size.
  3207     otherDigitByteArray := aLargeInteger digitBytes.
  3224     otherDigitByteArray := aLargeInteger digitBytes.
  3208     len2 := otherDigitByteArray size.
  3225     len2 := otherDigitByteArray size.
  3209 
  3226 
  3210     len1 > len2 ifTrue:[
  3227     len1 > len2 ifTrue:[
  3211         lResult := len1
  3228 	lResult := len1
  3212     ] ifFalse:[
  3229     ] ifFalse:[
  3213         lResult := (len1 max: len2) + 1.
  3230 	lResult := (len1 max: len2) + 1.
  3214     ].
  3231     ].
  3215     result := self class basicNew numberOfDigits:lResult.
  3232     result := self class basicNew numberOfDigits:lResult.
  3216     result sign:newSign.
  3233     result sign:newSign.
  3217     resultDigitByteArray := result digitBytes.
  3234     resultDigitByteArray := result digitBytes.
  3218 
  3235 
  3222     OBJ _digitByteArray = __INST(digitByteArray);
  3239     OBJ _digitByteArray = __INST(digitByteArray);
  3223 
  3240 
  3224     if (__isByteArray(_digitByteArray)
  3241     if (__isByteArray(_digitByteArray)
  3225      && __isByteArray(otherDigitByteArray)
  3242      && __isByteArray(otherDigitByteArray)
  3226      && __isByteArray(resultDigitByteArray)) {
  3243      && __isByteArray(resultDigitByteArray)) {
  3227         int __len1 = __intVal(len1);
  3244 	int __len1 = __intVal(len1);
  3228         int __len2 = __intVal(len2);
  3245 	int __len2 = __intVal(len2);
  3229         int __minLen = __len1 < __len2 ? __len1 : __len2;
  3246 	int __minLen = __len1 < __len2 ? __len1 : __len2;
  3230         int __index, __borrow = 0;
  3247 	int __index, __borrow = 0;
  3231         INT __diff;
  3248 	INT __diff;
  3232         unsigned char *__myDigits, *__otherDigits, *__resultDigits;
  3249 	unsigned char *__myDigits, *__otherDigits, *__resultDigits;
  3233 
  3250 
  3234         ok = true;
  3251 	ok = true;
  3235 
  3252 
  3236         __resultDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  3253 	__resultDigits = __ByteArrayInstPtr(resultDigitByteArray)->ba_element;
  3237         __otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  3254 	__otherDigits = __ByteArrayInstPtr(otherDigitByteArray)->ba_element;
  3238         __myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
  3255 	__myDigits = __ByteArrayInstPtr(_digitByteArray)->ba_element;
  3239 
  3256 
  3240         __index = 1;
  3257 	__index = 1;
  3241 
  3258 
  3242 #if defined(__LSBFIRST__)
  3259 #if defined(__LSBFIRST__)
  3243 # if __POINTER_SIZE__ == 8
  3260 # if __POINTER_SIZE__ == 8
  3244         /*
  3261 	/*
  3245          * subtract int-wise
  3262 	 * subtract int-wise
  3246          */
  3263 	 */
  3247         while ((__index+3) <= __minLen) {
  3264 	while ((__index+3) <= __minLen) {
  3248             /* do not make this into one expression - ask cg why */
  3265 	    /* do not make this into one expression - ask cg why */
  3249             __diff = ((unsigned int *)(__myDigits+__index-1))[0];
  3266 	    __diff = ((unsigned int *)(__myDigits+__index-1))[0];
  3250             __diff -= ((unsigned int *)(__otherDigits+__index-1))[0];
  3267 	    __diff -= ((unsigned int *)(__otherDigits+__index-1))[0];
  3251             __diff -= __borrow;
  3268 	    __diff -= __borrow;
  3252 
  3269 
  3253             if (__diff >= 0) {
  3270 	    if (__diff >= 0) {
  3254                 __borrow = 0;
  3271 		__borrow = 0;
  3255             } else {
  3272 	    } else {
  3256                 __borrow = 1;
  3273 		__borrow = 1;
  3257                 /* __diff += 0x10000; */
  3274 		/* __diff += 0x10000; */
  3258             }
  3275 	    }
  3259             ((unsigned int *)(__resultDigits+__index-1))[0] = __diff;
  3276 	    ((unsigned int *)(__resultDigits+__index-1))[0] = __diff;
  3260             __index += 4;
  3277 	    __index += 4;
  3261         }
  3278 	}
  3262 # endif /* 64bit */
  3279 # endif /* 64bit */
  3263 
  3280 
  3264         /*
  3281 	/*
  3265          * subtract short-wise
  3282 	 * subtract short-wise
  3266          */
  3283 	 */
  3267         while (__index < __minLen) {   /* i.e. index+1 <= minLen */
  3284 	while (__index < __minLen) {   /* i.e. index+1 <= minLen */
  3268             /* do not make this into one expression - ask cg why */
  3285 	    /* do not make this into one expression - ask cg why */
  3269             __diff = ((unsigned short *)(__myDigits+__index-1))[0];
  3286 	    __diff = ((unsigned short *)(__myDigits+__index-1))[0];
  3270             __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
  3287 	    __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
  3271             __diff -= __borrow;
  3288 	    __diff -= __borrow;
  3272             if (__diff >= 0) {
  3289 	    if (__diff >= 0) {
  3273                 __borrow = 0;
  3290 		__borrow = 0;
  3274             } else {
  3291 	    } else {
  3275                 __borrow = 1;
  3292 		__borrow = 1;
  3276                 /* __diff += 0x10000; */
  3293 		/* __diff += 0x10000; */
  3277             }
  3294 	    }
  3278             ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3295 	    ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3279             __index += 2;
  3296 	    __index += 2;
  3280         }
  3297 	}
  3281 
  3298 
  3282         if (__index == __minLen) {
  3299 	if (__index == __minLen) {
  3283             /* one of the operands has odd length - cannot continue short-wise */
  3300 	    /* one of the operands has odd length - cannot continue short-wise */
  3284         } else {
  3301 	} else {
  3285             if (__len1 > __len2) {
  3302 	    if (__len1 > __len2) {
  3286                 while (__index < __len1) {
  3303 		while (__index < __len1) {
  3287                     /* do not make this into one expression - ask cg why */
  3304 		    /* do not make this into one expression - ask cg why */
  3288                     __diff = ((unsigned short *)(__myDigits+__index-1))[0];
  3305 		    __diff = ((unsigned short *)(__myDigits+__index-1))[0];
  3289                     __diff -= __borrow;
  3306 		    __diff -= __borrow;
  3290                     if (__diff >= 0) {
  3307 		    if (__diff >= 0) {
  3291                         __borrow = 0;
  3308 			__borrow = 0;
  3292                         ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3309 			((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3293                         __index += 2;
  3310 			__index += 2;
  3294 
  3311 
  3295                         /* copy over rest */
  3312 			/* copy over rest */
  3296                         while (__index < __len1) {
  3313 			while (__index < __len1) {
  3297                             ((unsigned short *)(__resultDigits+__index-1))[0] = ((unsigned short *)(__myDigits+__index-1))[0];
  3314 			    ((unsigned short *)(__resultDigits+__index-1))[0] = ((unsigned short *)(__myDigits+__index-1))[0];
  3298                             __index+=2;
  3315 			    __index+=2;
  3299                         }
  3316 			}
  3300                         if (__index <= __len1) {
  3317 			if (__index <= __len1) {
  3301                             __resultDigits[__index-1] = __myDigits[__index-1];
  3318 			    __resultDigits[__index-1] = __myDigits[__index-1];
  3302                             __index++;
  3319 			    __index++;
  3303                         }
  3320 			}
  3304                         break;
  3321 			break;
  3305                     }
  3322 		    }
  3306                     __borrow = 1;
  3323 		    __borrow = 1;
  3307                     /* __diff += 0x10000; */
  3324 		    /* __diff += 0x10000; */
  3308                     ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3325 		    ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3309                     __index += 2;
  3326 		    __index += 2;
  3310                 }
  3327 		}
  3311             } else {
  3328 	    } else {
  3312                 if (__len2 > __len1) {
  3329 		if (__len2 > __len1) {
  3313                     while (__index < __len2) {
  3330 		    while (__index < __len2) {
  3314                         /* do not make this into one expression - ask cg why */
  3331 			/* do not make this into one expression - ask cg why */
  3315                         __diff = 0;
  3332 			__diff = 0;
  3316                         __diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
  3333 			__diff -= ((unsigned short *)(__otherDigits+__index-1))[0];
  3317                         __diff -= __borrow;
  3334 			__diff -= __borrow;
  3318                         if (__diff >= 0) {
  3335 			if (__diff >= 0) {
  3319                             __borrow = 0;
  3336 			    __borrow = 0;
  3320                         } else {
  3337 			} else {
  3321                             __borrow = 1;
  3338 			    __borrow = 1;
  3322                             /* __diff += 0x10000; */
  3339 			    /* __diff += 0x10000; */
  3323                         }
  3340 			}
  3324                         ((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3341 			((unsigned short *)(__resultDigits+__index-1))[0] = __diff;
  3325                         __index += 2;
  3342 			__index += 2;
  3326                     }
  3343 		    }
  3327                 }
  3344 		}
  3328             }
  3345 	    }
  3329         }
  3346 	}
  3330 #endif
  3347 #endif
  3331         /*
  3348 	/*
  3332          * subtract byte-wise
  3349 	 * subtract byte-wise
  3333          */
  3350 	 */
  3334         while (__index <= __minLen) {
  3351 	while (__index <= __minLen) {
  3335             /* do not make this into one expression - ask cg why */
  3352 	    /* do not make this into one expression - ask cg why */
  3336             __diff = __myDigits[__index-1];
  3353 	    __diff = __myDigits[__index-1];
  3337             __diff -= __otherDigits[__index-1];
  3354 	    __diff -= __otherDigits[__index-1];
  3338             __diff -= __borrow;
  3355 	    __diff -= __borrow;
  3339             if (__diff >= 0) {
  3356 	    if (__diff >= 0) {
  3340                 __borrow = 0;
  3357 		__borrow = 0;
  3341             } else {
  3358 	    } else {
  3342                 __borrow = 1;
  3359 		__borrow = 1;
  3343                 /* __diff += 0x100; */
  3360 		/* __diff += 0x100; */
  3344             }
  3361 	    }
  3345             __resultDigits[__index-1] = __diff;
  3362 	    __resultDigits[__index-1] = __diff;
  3346             __index++;
  3363 	    __index++;
  3347         }
  3364 	}
  3348 
  3365 
  3349         if (__len1 > __len2) {
  3366 	if (__len1 > __len2) {
  3350             while (__index <= __len1) {
  3367 	    while (__index <= __len1) {
  3351                 /* do not make this into one expression - ask cg why */
  3368 		/* do not make this into one expression - ask cg why */
  3352                 __diff = __myDigits[__index-1];
  3369 		__diff = __myDigits[__index-1];
  3353                 __diff -= __borrow;
  3370 		__diff -= __borrow;
  3354                 if (__diff >= 0) {
  3371 		if (__diff >= 0) {
  3355                     __borrow = 0;
  3372 		    __borrow = 0;
  3356                     /* copy over rest */
  3373 		    /* copy over rest */
  3357                     __resultDigits[__index-1] = __diff;
  3374 		    __resultDigits[__index-1] = __diff;
  3358                     __index++;
  3375 		    __index++;
  3359                     while (__index <= __len1) {
  3376 		    while (__index <= __len1) {
  3360                         __resultDigits[__index-1] = __myDigits[__index-1];
  3377 			__resultDigits[__index-1] = __myDigits[__index-1];
  3361                         __index++;
  3378 			__index++;
  3362                     }
  3379 		    }
  3363                     break;
  3380 		    break;
  3364                 }
  3381 		}
  3365                 __borrow = 1;
  3382 		__borrow = 1;
  3366                 /* __diff += 0x100; */
  3383 		/* __diff += 0x100; */
  3367                 __resultDigits[__index-1] = __diff;
  3384 		__resultDigits[__index-1] = __diff;
  3368                 __index++;
  3385 		__index++;
  3369             }
  3386 	    }
  3370         } else {
  3387 	} else {
  3371             if (__len2 > __len1) {
  3388 	    if (__len2 > __len1) {
  3372                 while (__index <= __len2) {
  3389 		while (__index <= __len2) {
  3373                     /* do not make this into one expression - ask cg why */
  3390 		    /* do not make this into one expression - ask cg why */
  3374                     __diff = 0;
  3391 		    __diff = 0;
  3375                     __diff -= __otherDigits[__index-1];
  3392 		    __diff -= __otherDigits[__index-1];
  3376                     __diff -= __borrow;
  3393 		    __diff -= __borrow;
  3377                     if (__diff >= 0) {
  3394 		    if (__diff >= 0) {
  3378                         __borrow = 0;
  3395 			__borrow = 0;
  3379                     } else {
  3396 		    } else {
  3380                         __borrow = 1;
  3397 			__borrow = 1;
  3381                         /* __diff += 0x100; */
  3398 			/* __diff += 0x100; */
  3382                     }
  3399 		    }
  3383                     __resultDigits[__index-1] = __diff;
  3400 		    __resultDigits[__index-1] = __diff;
  3384                     __index++;
  3401 		    __index++;
  3385                 }
  3402 		}
  3386             }
  3403 	    }
  3387         }
  3404 	}
  3388         borrow = __mkSmallInteger(__borrow);
  3405 	borrow = __mkSmallInteger(__borrow);
  3389         index = __mkSmallInteger(__index);
  3406 	index = __mkSmallInteger(__index);
  3390         lastDigit = __mkSmallInteger(__resultDigits[__intVal(lResult)-1]);
  3407 	lastDigit = __mkSmallInteger(__resultDigits[__intVal(lResult)-1]);
  3391     }
  3408     }
  3392 %}.
  3409 %}.
  3393     ok == true ifFalse:[
  3410     ok == true ifFalse:[
  3394         index := 1.
  3411 	index := 1.
  3395         borrow := 0.
  3412 	borrow := 0.
  3396 
  3413 
  3397         done := false.
  3414 	done := false.
  3398         [done] whileFalse:[
  3415 	[done] whileFalse:[
  3399             diff := borrow.
  3416 	    diff := borrow.
  3400             (index <= len1) ifTrue:[
  3417 	    (index <= len1) ifTrue:[
  3401                 diff := diff + (digitByteArray basicAt:index).
  3418 		diff := diff + (digitByteArray basicAt:index).
  3402                 (index <= len2) ifTrue:[
  3419 		(index <= len2) ifTrue:[
  3403                     diff := diff - (otherDigitByteArray basicAt:index)
  3420 		    diff := diff - (otherDigitByteArray basicAt:index)
  3404                 ]
  3421 		]
  3405             ] ifFalse:[
  3422 	    ] ifFalse:[
  3406                 (index <= len2) ifTrue:[
  3423 		(index <= len2) ifTrue:[
  3407                     diff := diff - (otherDigitByteArray basicAt:index)
  3424 		    diff := diff - (otherDigitByteArray basicAt:index)
  3408                 ] ifFalse:[
  3425 		] ifFalse:[
  3409                     "end reached"
  3426 		    "end reached"
  3410                     done := true
  3427 		    done := true
  3411                 ]
  3428 		]
  3412             ].
  3429 	    ].
  3413 
  3430 
  3414             "/ workaround for
  3431 	    "/ workaround for
  3415             "/ gcc code generator bug
  3432 	    "/ gcc code generator bug
  3416 
  3433 
  3417             (diff >= 0) ifTrue:[
  3434 	    (diff >= 0) ifTrue:[
  3418                 borrow := 0
  3435 		borrow := 0
  3419             ] ifFalse:[
  3436 	    ] ifFalse:[
  3420                 borrow := -1.
  3437 		borrow := -1.
  3421                 diff := diff + 16r100
  3438 		diff := diff + 16r100
  3422             ].
  3439 	    ].
  3423 
  3440 
  3424     "/        (diff < 0) ifTrue:[
  3441     "/        (diff < 0) ifTrue:[
  3425     "/            borrow := -1.
  3442     "/            borrow := -1.
  3426     "/            diff := diff + 16r100
  3443     "/            diff := diff + 16r100
  3427     "/        ] ifFalse:[
  3444     "/        ] ifFalse:[
  3428     "/            borrow := 0
  3445     "/            borrow := 0
  3429     "/        ].
  3446     "/        ].
  3430 
  3447 
  3431             resultDigitByteArray basicAt:index put:diff.
  3448 	    resultDigitByteArray basicAt:index put:diff.
  3432             index := index + 1
  3449 	    index := index + 1
  3433         ].
  3450 	].
  3434         lastDigit := resultDigitByteArray basicAt:lResult.
  3451 	lastDigit := resultDigitByteArray basicAt:lResult.
  3435     ].
  3452     ].
  3436 
  3453 
  3437     (borrow ~~ 0) ifTrue:[
  3454     (borrow ~~ 0) ifTrue:[
  3438         "/ must generate 255's complement
  3455 	"/ must generate 255's complement
  3439 
  3456 
  3440         result sign:newSign negated.
  3457 	result sign:newSign negated.
  3441         [index <= lResult] whileTrue:[
  3458 	[index <= lResult] whileTrue:[
  3442             resultDigitByteArray basicAt:index put:16rFF.
  3459 	    resultDigitByteArray basicAt:index put:16rFF.
  3443             index := index + 1.
  3460 	    index := index + 1.
  3444         ].
  3461 	].
  3445         index := lResult.
  3462 	index := lResult.
  3446         [index > 0] whileTrue:[
  3463 	[index > 0] whileTrue:[
  3447             resultDigitByteArray basicAt:index put:(255 - (resultDigitByteArray at:index)).
  3464 	    resultDigitByteArray basicAt:index put:(255 - (resultDigitByteArray at:index)).
  3448             index := index - 1.
  3465 	    index := index - 1.
  3449         ].
  3466 	].
  3450 
  3467 
  3451         index := 1.
  3468 	index := 1.
  3452         carry := 1.
  3469 	carry := 1.
  3453         [carry ~~ 0] whileTrue:[
  3470 	[carry ~~ 0] whileTrue:[
  3454             (index <= lResult) ifTrue:[
  3471 	    (index <= lResult) ifTrue:[
  3455                 carry := (resultDigitByteArray basicAt:index) + carry.
  3472 		carry := (resultDigitByteArray basicAt:index) + carry.
  3456             ].
  3473 	    ].
  3457             resultDigitByteArray basicAt:index put:(carry bitAnd:16rFF).
  3474 	    resultDigitByteArray basicAt:index put:(carry bitAnd:16rFF).
  3458             carry := carry bitShift:-8.
  3475 	    carry := carry bitShift:-8.
  3459             index := index + 1
  3476 	    index := index + 1
  3460         ].
  3477 	].
  3461         lastDigit := resultDigitByteArray basicAt:lResult.
  3478 	lastDigit := resultDigitByteArray basicAt:lResult.
  3462     ].
  3479     ].
  3463     (lastDigit ~~ 0 and:[lResult > SmallInteger maxBytes]) ifTrue:[
  3480     (lastDigit ~~ 0 and:[lResult > SmallInteger maxBytes]) ifTrue:[
  3464         ^ result
  3481 	^ result
  3465     ].
  3482     ].
  3466     ^ result compressed
  3483     ^ result compressed
  3467 
  3484 
  3468     "Modified: 5.11.1996 / 14:09:25 / cg"
  3485     "Modified: 5.11.1996 / 14:09:25 / cg"
  3469 !
  3486 !
  4820 ! !
  4837 ! !
  4821 
  4838 
  4822 !LargeInteger class methodsFor:'documentation'!
  4839 !LargeInteger class methodsFor:'documentation'!
  4823 
  4840 
  4824 version
  4841 version
  4825     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.194 2009-05-26 06:37:56 cg Exp $'
  4842     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.195 2009-09-14 22:16:50 cg Exp $'
  4826 ! !
  4843 ! !