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 ! |
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 |
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. |
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. |
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. |
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 ! |