189 " |
189 " |
190 this is the common case, subtracting a SmallInteger. |
190 this is the common case, subtracting a SmallInteger. |
191 Use a special method for this case ... |
191 Use a special method for this case ... |
192 " |
192 " |
193 (aNumber class == SmallInteger) ifTrue:[ |
193 (aNumber class == SmallInteger) ifTrue:[ |
194 sign < 0 ifTrue:[ |
194 sign < 0 ifTrue:[ |
195 aNumber > 0 ifTrue:[ |
195 aNumber > 0 ifTrue:[ |
196 ^ (self absFastPlus:aNumber) sign:-1 |
196 ^ (self absFastPlus:aNumber) sign:-1 |
197 ]. |
197 ]. |
198 ^ (self absFastMinus:aNumber) sign:-1 |
198 ^ (self absFastMinus:aNumber) sign:-1 |
199 ]. |
199 ]. |
200 aNumber > 0 ifTrue:[ |
200 aNumber > 0 ifTrue:[ |
201 ^ self absFastMinus:aNumber |
201 ^ self absFastMinus:aNumber |
202 ]. |
202 ]. |
203 ^ self absFastPlus:aNumber |
203 ^ self absFastPlus:aNumber |
204 ]. |
204 ]. |
205 |
205 |
206 " |
206 " |
207 if the argument is not a largeInteger, coerce |
207 if the argument is not a largeInteger, coerce |
208 " |
208 " |
209 (aNumber class == self class) ifFalse:[ |
209 (aNumber class == self class) ifFalse:[ |
210 ^ self retry:#- coercing:aNumber |
210 ^ self retry:#- coercing:aNumber |
211 ]. |
211 ]. |
212 |
212 |
213 otherSign := aNumber sign. |
213 otherSign := aNumber sign. |
214 (sign > 0) ifTrue:[ |
214 (sign > 0) ifTrue:[ |
215 "I am positive" |
215 "I am positive" |
216 (otherSign > 0) ifTrue:[^ self absMinus:aNumber]. |
216 (otherSign > 0) ifTrue:[^ self absMinus:aNumber]. |
217 (otherSign < 0) ifTrue:[^ self absPlus:aNumber]. |
217 (otherSign < 0) ifTrue:[^ self absPlus:aNumber]. |
218 ^ self |
218 ^ self |
219 ]. |
219 ]. |
220 "I am negative" |
220 "I am negative" |
221 (otherSign > 0) ifTrue:[^ (self absPlus:aNumber) negated]. |
221 (otherSign > 0) ifTrue:[^ (self absPlus:aNumber) negated]. |
222 (otherSign < 0) ifTrue:[^ (self absMinus:aNumber) negated]. |
222 (otherSign < 0) ifTrue:[^ (self absMinus:aNumber) negated]. |
223 ^ self |
223 ^ self |
264 " |
264 " |
265 this is the common case, dividing by a SmallInteger. |
265 this is the common case, dividing by a SmallInteger. |
266 Use a special method for this case ... |
266 Use a special method for this case ... |
267 " |
267 " |
268 (aNumber class == SmallInteger) ifTrue:[ |
268 (aNumber class == SmallInteger) ifTrue:[ |
269 abs := aNumber. |
269 abs := aNumber. |
270 abs := abs abs. |
270 abs := abs abs. |
271 (abs between:1 and:16r003fffff) ifTrue:[ |
271 (abs between:1 and:16r003fffff) ifTrue:[ |
272 divMod := self absFastDiv:abs. |
272 divMod := self absFastDiv:abs. |
273 quo := divMod at:1. |
273 quo := divMod at:1. |
274 (sign == otherSign) ifTrue:[^ quo]. |
274 (sign == otherSign) ifTrue:[^ quo]. |
275 |
275 |
276 "/ stupid adjust ... |
276 "/ stupid adjust ... |
277 (divMod at:2) == 0 ifFalse:[ |
277 (divMod at:2) == 0 ifFalse:[ |
278 ^ (quo sign:-1) - 1 |
278 ^ (quo sign:-1) - 1 |
279 ]. |
279 ]. |
280 ^ quo sign:-1 |
280 ^ quo sign:-1 |
281 ]. |
281 ]. |
282 n := aNumber asLargeInteger. |
282 n := aNumber asLargeInteger. |
283 ] ifFalse:[ |
283 ] ifFalse:[ |
284 n := aNumber |
284 n := aNumber |
285 ]. |
285 ]. |
286 |
286 |
287 " |
287 " |
288 if the argument is not a largeInteger, coerce |
288 if the argument is not a largeInteger, coerce |
289 " |
289 " |
290 (n class == self class) ifFalse:[ |
290 (n class == self class) ifFalse:[ |
291 ^ self retry:#// coercing:aNumber |
291 ^ self retry:#// coercing:aNumber |
292 ]. |
292 ]. |
293 |
293 |
294 divMod := self absDiv:n. |
294 divMod := self absDiv:n. |
295 |
295 |
296 (sign == otherSign) ifTrue:[^ divMod at:1]. |
296 (sign == otherSign) ifTrue:[^ divMod at:1]. |
297 |
297 |
298 "/ stupid adjust for truncation ... |
298 "/ stupid adjust for truncation ... |
299 quo := divMod at:1. |
299 quo := divMod at:1. |
300 (divMod at:2) == 0 ifFalse:[ |
300 (divMod at:2) == 0 ifFalse:[ |
301 ^ (quo sign:-1) - 1 |
301 ^ (quo sign:-1) - 1 |
302 ]. |
302 ]. |
303 ^ quo sign:-1 |
303 ^ quo sign:-1 |
304 |
304 |
305 " |
305 " |
306 900 // 400 |
306 900 // 400 |
338 " |
338 " |
339 this is the common case, dividing by a SmallInteger. |
339 this is the common case, dividing by a SmallInteger. |
340 Use a special method for this case ... |
340 Use a special method for this case ... |
341 " |
341 " |
342 (aNumber class == SmallInteger) ifTrue:[ |
342 (aNumber class == SmallInteger) ifTrue:[ |
343 (abs between:1 and:16r003fffff) ifTrue:[ |
343 (abs between:1 and:16r003fffff) ifTrue:[ |
344 rem := (self absFastDiv:abs) at:2. |
344 rem := (self absFastDiv:abs) at:2. |
345 ] ifFalse:[ |
345 ] ifFalse:[ |
346 rem := (self absDiv:abs asLargeInteger) at:2 |
346 rem := (self absDiv:abs asLargeInteger) at:2 |
347 ]. |
347 ]. |
348 ] ifFalse:[ |
348 ] ifFalse:[ |
349 " |
349 " |
350 if the argument is not a largeInteger, coerce |
350 if the argument is not a largeInteger, coerce |
351 " |
351 " |
352 (aNumber class == self class) ifFalse:[ |
352 (aNumber class == self class) ifFalse:[ |
353 ^ self retry:#\\ coercing:aNumber |
353 ^ self retry:#\\ coercing:aNumber |
354 ]. |
354 ]. |
355 |
355 |
356 rem := (self absDiv:abs) at:2. |
356 rem := (self absDiv:abs) at:2. |
357 ]. |
357 ]. |
358 |
358 |
359 aNumber negative ifTrue:[ |
359 aNumber negative ifTrue:[ |
360 ^ rem sign:-1 |
360 ^ rem sign:-1 |
361 ]. |
361 ]. |
362 ^ rem |
362 ^ rem |
363 |
363 |
364 " |
364 " |
365 900 \\ 400 |
365 900 \\ 400 |
402 " |
402 " |
403 this is the common case, dividing by a SmallInteger. |
403 this is the common case, dividing by a SmallInteger. |
404 Use a special method for this case ... |
404 Use a special method for this case ... |
405 " |
405 " |
406 (aNumber class == SmallInteger) ifTrue:[ |
406 (aNumber class == SmallInteger) ifTrue:[ |
407 ^ self absFastDiv:aNumber abs. |
407 ^ self absFastDiv:aNumber abs. |
408 ]. |
408 ]. |
409 |
409 |
410 " |
410 " |
411 if the argument is not a largeInteger, coerce |
411 if the argument is not a largeInteger, coerce |
412 " |
412 " |
413 (aNumber class == self class) ifTrue:[ |
413 (aNumber class == self class) ifTrue:[ |
414 ^ self absDiv:aNumber abs |
414 ^ self absDiv:aNumber abs |
415 ]. |
415 ]. |
416 |
416 |
417 ^ super divMod:aNumber |
417 ^ super divMod:aNumber |
418 |
418 |
419 " |
419 " |
470 " |
470 " |
471 this is the common case, dividing by a SmallInteger. |
471 this is the common case, dividing by a SmallInteger. |
472 Use a special method for this case ... |
472 Use a special method for this case ... |
473 " |
473 " |
474 (aNumber class == SmallInteger) ifTrue:[ |
474 (aNumber class == SmallInteger) ifTrue:[ |
475 abs := aNumber. |
475 abs := aNumber. |
476 abs := abs abs. |
476 abs := abs abs. |
477 (abs between:1 and:16r003fffff) ifTrue:[ |
477 (abs between:1 and:16r003fffff) ifTrue:[ |
478 quo := (self absFastDiv:abs) at:1. |
478 quo := (self absFastDiv:abs) at:1. |
479 (sign == otherSign) ifTrue:[^ quo]. |
479 (sign == otherSign) ifTrue:[^ quo]. |
480 ^ quo sign:-1 |
480 ^ quo sign:-1 |
481 ] |
481 ] |
482 ]. |
482 ]. |
483 |
483 |
484 " |
484 " |
485 if the argument is not a largeInteger, coerce |
485 if the argument is not a largeInteger, coerce |
486 " |
486 " |
487 (aNumber class == self class) ifFalse:[ |
487 (aNumber class == self class) ifFalse:[ |
488 ^ self retry:#quo: coercing:aNumber |
488 ^ self retry:#quo: coercing:aNumber |
489 ]. |
489 ]. |
490 |
490 |
491 sign < 0 ifTrue:[ |
491 sign < 0 ifTrue:[ |
492 (sign == otherSign) ifTrue:[^ (self absDiv:aNumber negated) at:1]. |
492 (sign == otherSign) ifTrue:[^ (self absDiv:aNumber negated) at:1]. |
493 ] ifFalse:[ |
493 ] ifFalse:[ |
494 (sign == otherSign) ifTrue:[^ (self absDiv:aNumber) at:1]. |
494 (sign == otherSign) ifTrue:[^ (self absDiv:aNumber) at:1]. |
495 ]. |
495 ]. |
496 ^ ((self absDiv:aNumber) at:1) sign:-1 |
496 ^ ((self absDiv:aNumber) at:1) sign:-1 |
497 |
497 |
498 " |
498 " |
499 900 // 400 |
499 900 // 400 |
529 " |
529 " |
530 this is the common case, dividing by a SmallInteger. |
530 this is the common case, dividing by a SmallInteger. |
531 Use special code for this case ... |
531 Use special code for this case ... |
532 " |
532 " |
533 (aNumber class == SmallInteger) ifTrue:[ |
533 (aNumber class == SmallInteger) ifTrue:[ |
534 abs := aNumber. |
534 abs := aNumber. |
535 abs := abs abs. |
535 abs := abs abs. |
536 (abs between:1 and:16r003fffff) ifTrue:[ |
536 (abs between:1 and:16r003fffff) ifTrue:[ |
537 rem := (self absFastDiv:abs) at:2. |
537 rem := (self absFastDiv:abs) at:2. |
538 ] ifFalse:[ |
538 ] ifFalse:[ |
539 rem := (self absDiv:(abs asLargeInteger)) at:2 |
539 rem := (self absDiv:(abs asLargeInteger)) at:2 |
540 ]. |
540 ]. |
541 ] ifFalse:[ |
541 ] ifFalse:[ |
542 " |
542 " |
543 if the argument is not a largeInteger, coerce |
543 if the argument is not a largeInteger, coerce |
544 " |
544 " |
545 (aNumber class == self class) ifFalse:[ |
545 (aNumber class == self class) ifFalse:[ |
546 ^ self retry:#\\ coercing:aNumber |
546 ^ self retry:#\\ coercing:aNumber |
547 ]. |
547 ]. |
548 |
548 |
549 rem := (self absDiv:aNumber) at:2 |
549 rem := (self absDiv:aNumber) at:2 |
550 ]. |
550 ]. |
551 |
551 |
552 sign < 0 ifTrue:[ |
552 sign < 0 ifTrue:[ |
553 ^ rem sign:-1 |
553 ^ rem sign:-1 |
554 ]. |
554 ]. |
555 ^ rem |
555 ^ rem |
556 |
556 |
557 " |
557 " |
558 900 \\ 400 |
558 900 \\ 400 |
689 |
689 |
690 %{ /* NOCONTEXT */ |
690 %{ /* NOCONTEXT */ |
691 OBJ t; |
691 OBJ t; |
692 |
692 |
693 if (__INST(sign) == __MKSMALLINT(0)) { |
693 if (__INST(sign) == __MKSMALLINT(0)) { |
694 RETURN (__MKSMALLINT(0)); |
694 RETURN (__MKSMALLINT(0)); |
695 } |
695 } |
696 |
696 |
697 t = __INST(digitByteArray); |
697 t = __INST(digitByteArray); |
698 if (__isByteArray(t)) { |
698 if (__isByteArray(t)) { |
699 unsigned char *_digitBytes = __ByteArrayInstPtr(t)->ba_element; |
699 unsigned char *_digitBytes = __ByteArrayInstPtr(t)->ba_element; |
700 int _idx = _byteArraySize(t); |
700 int _idx = _byteArraySize(t); |
701 int _val; |
701 int _val; |
702 |
702 |
703 while ((_idx > 0) && (_digitBytes[_idx - 1] == 0)) { |
703 while ((_idx > 0) && (_digitBytes[_idx - 1] == 0)) { |
704 _idx--; |
704 _idx--; |
705 } |
705 } |
706 switch (_idx) { |
706 switch (_idx) { |
707 case 0: |
707 case 0: |
708 RETURN (__MKSMALLINT(0)); |
708 RETURN (__MKSMALLINT(0)); |
709 break; |
709 break; |
710 |
710 |
711 case 1: |
711 case 1: |
712 _val = _digitBytes[0]; |
712 _val = _digitBytes[0]; |
713 if (__INST(sign) == __MKSMALLINT(-1)) |
713 if (__INST(sign) == __MKSMALLINT(-1)) |
714 _val = -_val; |
714 _val = -_val; |
715 RETURN (__MKSMALLINT(_val)); |
715 RETURN (__MKSMALLINT(_val)); |
716 |
716 |
717 case 2: |
717 case 2: |
718 _val = (_digitBytes[1]<<8) + _digitBytes[0]; |
718 _val = (_digitBytes[1]<<8) + _digitBytes[0]; |
719 if (__INST(sign) == __MKSMALLINT(-1)) |
719 if (__INST(sign) == __MKSMALLINT(-1)) |
720 _val = -_val; |
720 _val = -_val; |
721 RETURN (__MKSMALLINT(_val)); |
721 RETURN (__MKSMALLINT(_val)); |
722 |
722 |
723 case 3: |
723 case 3: |
724 _val = (((_digitBytes[2]<<8) + _digitBytes[1])<<8) + _digitBytes[0]; |
724 _val = (((_digitBytes[2]<<8) + _digitBytes[1])<<8) + _digitBytes[0]; |
725 if (__INST(sign) == __MKSMALLINT(-1)) |
725 if (__INST(sign) == __MKSMALLINT(-1)) |
726 _val = -_val; |
726 _val = -_val; |
727 RETURN (__MKSMALLINT(_val)); |
727 RETURN (__MKSMALLINT(_val)); |
728 |
728 |
729 case 4: |
729 case 4: |
730 _val = _digitBytes[3]; |
730 _val = _digitBytes[3]; |
731 if (_val <= 0x40) { |
731 if (_val <= 0x40) { |
732 _val = (((((_val<<8) + _digitBytes[2])<<8) + _digitBytes[1])<<8) + _digitBytes[0]; |
732 _val = (((((_val<<8) + _digitBytes[2])<<8) + _digitBytes[1])<<8) + _digitBytes[0]; |
733 if (__INST(sign) == __MKSMALLINT(-1)) |
733 if (__INST(sign) == __MKSMALLINT(-1)) |
734 _val = -_val; |
734 _val = -_val; |
735 if ((_val >= _MIN_INT) && (_val <= _MAX_INT)) { |
735 if ((_val >= _MIN_INT) && (_val <= _MAX_INT)) { |
736 RETURN (__MKSMALLINT(_val)); |
736 RETURN (__MKSMALLINT(_val)); |
737 } |
737 } |
738 } |
738 } |
739 break; |
739 break; |
740 |
740 |
741 default: |
741 default: |
742 break; |
742 break; |
743 } |
743 } |
744 } |
744 } |
745 %}. |
745 %}. |
746 index := digitByteArray size. |
746 index := digitByteArray size. |
747 [(index > 0) and:[(digitByteArray at:index) == 0]] whileTrue:[ |
747 [(index > 0) and:[(digitByteArray at:index) == 0]] whileTrue:[ |
748 index := index - 1 |
748 index := index - 1 |
749 ]. |
749 ]. |
750 |
750 |
751 (index ~~ digitByteArray size) ifTrue:[ |
751 (index ~~ digitByteArray size) ifTrue:[ |
752 digitByteArray := digitByteArray copyFrom:1 to:index |
752 digitByteArray := digitByteArray copyFrom:1 to:index |
753 ]. |
753 ]. |
754 ^ self |
754 ^ self |
755 ! |
755 ! |
756 |
756 |
757 value:aSmallInteger |
757 value:aSmallInteger |
767 could have simply created a 4-byte largeinteger and normalize |
767 could have simply created a 4-byte largeinteger and normalize |
768 it; the code below does the normalize right away, avoiding the |
768 it; the code below does the normalize right away, avoiding the |
769 overhead of producing any intermediate byte-arrays (and the scanning) |
769 overhead of producing any intermediate byte-arrays (and the scanning) |
770 " |
770 " |
771 (aSmallInteger == 0) ifTrue: [ |
771 (aSmallInteger == 0) ifTrue: [ |
772 digitByteArray := ByteArray with:0. |
772 digitByteArray := ByteArray with:0. |
773 sign := 0. |
773 sign := 0. |
774 ^ self |
774 ^ self |
775 ]. |
775 ]. |
776 (aSmallInteger < 0) ifTrue: [ |
776 (aSmallInteger < 0) ifTrue: [ |
777 sign := -1. |
777 sign := -1. |
778 absValue := aSmallInteger negated |
778 absValue := aSmallInteger negated |
779 ] ifFalse: [ |
779 ] ifFalse: [ |
780 sign := 1. |
780 sign := 1. |
781 absValue := aSmallInteger |
781 absValue := aSmallInteger |
782 ]. |
782 ]. |
783 b1 := absValue bitAnd:16rFF. |
783 b1 := absValue bitAnd:16rFF. |
784 absValue := absValue bitShift:-8. |
784 absValue := absValue bitShift:-8. |
785 absValue == 0 ifTrue:[ |
785 absValue == 0 ifTrue:[ |
786 digitByteArray := ByteArray with:b1 |
786 digitByteArray := ByteArray with:b1 |
787 ] ifFalse:[ |
787 ] ifFalse:[ |
788 b2 := absValue bitAnd:16rFF. |
788 b2 := absValue bitAnd:16rFF. |
789 absValue := absValue bitShift:-8. |
789 absValue := absValue bitShift:-8. |
790 absValue == 0 ifTrue:[ |
790 absValue == 0 ifTrue:[ |
791 digitByteArray := ByteArray with:b1 with:b2 |
791 digitByteArray := ByteArray with:b1 with:b2 |
792 ] ifFalse:[ |
792 ] ifFalse:[ |
793 b3 := absValue bitAnd:16rFF. |
793 b3 := absValue bitAnd:16rFF. |
794 absValue := absValue bitShift:-8. |
794 absValue := absValue bitShift:-8. |
795 absValue == 0 ifTrue:[ |
795 absValue == 0 ifTrue:[ |
796 digitByteArray := ByteArray with:b1 with:b2 with:b3 |
796 digitByteArray := ByteArray with:b1 with:b2 with:b3 |
797 ] ifFalse:[ |
797 ] ifFalse:[ |
798 digitByteArray := ByteArray with:b1 with:b2 with:b3 with:absValue |
798 digitByteArray := ByteArray with:b1 with:b2 with:b3 with:absValue |
799 ] |
799 ] |
800 ] |
800 ] |
801 ] |
801 ] |
802 |
802 |
803 "Modified: 5.11.1996 / 16:15:39 / cg" |
803 "Modified: 5.11.1996 / 16:15:39 / cg" |
804 ! ! |
804 ! ! |
805 |
805 |
873 differenceFromInteger:anInteger |
873 differenceFromInteger:anInteger |
874 "sent, when anInteger does not know how to subtract the receiver. |
874 "sent, when anInteger does not know how to subtract the receiver. |
875 Return the result of 'anInteger - self'. The argument must be a SmallInteger." |
875 Return the result of 'anInteger - self'. The argument must be a SmallInteger." |
876 |
876 |
877 anInteger > 0 ifTrue:[ |
877 anInteger > 0 ifTrue:[ |
878 sign > 0 ifTrue:[ |
878 sign > 0 ifTrue:[ |
879 ^ (self absFastMinus:anInteger) sign:-1 |
879 ^ (self absFastMinus:anInteger) sign:-1 |
880 ]. |
880 ]. |
881 ^ self absFastPlus:anInteger |
881 ^ self absFastPlus:anInteger |
882 ]. |
882 ]. |
883 anInteger == 0 ifTrue:[ |
883 anInteger == 0 ifTrue:[ |
884 ^ self negated |
884 ^ self negated |
885 ]. |
885 ]. |
886 sign > 0 ifTrue:[ |
886 sign > 0 ifTrue:[ |
887 ^ (self absFastPlus:anInteger negated) sign:-1 |
887 ^ (self absFastPlus:anInteger negated) sign:-1 |
888 ]. |
888 ]. |
889 ^ (self absFastMinus:anInteger) sign:-1 |
889 ^ (self absFastMinus:anInteger) sign:-1 |
890 |
890 |
891 " |
891 " |
892 12345678901234567890 |
892 12345678901234567890 |
919 anInteger == 0 ifTrue:[^ 0]. |
919 anInteger == 0 ifTrue:[^ 0]. |
920 anInteger == 1 ifTrue:[^ self]. |
920 anInteger == 1 ifTrue:[^ self]. |
921 |
921 |
922 num := anInteger abs. |
922 num := anInteger abs. |
923 (num > 16r3FFFFF) ifTrue:[ |
923 (num > 16r3FFFFF) ifTrue:[ |
924 "if num is too big (so that multiplying by a byte could create a Large)" |
924 "if num is too big (so that multiplying by a byte could create a Large)" |
925 |
925 |
926 ^ anInteger retry:#* coercing:self |
926 ^ anInteger retry:#* coercing:self |
927 ]. |
927 ]. |
928 |
928 |
929 len := digitByteArray size. |
929 len := digitByteArray size. |
930 |
930 |
931 result := self class basicNew numberOfDigits:(len + 4). |
931 result := self class basicNew numberOfDigits:(len + 4). |
932 |
932 |
933 anInteger < 0 ifTrue:[ |
933 anInteger < 0 ifTrue:[ |
934 sign > 0 ifTrue:[ |
934 sign > 0 ifTrue:[ |
935 result sign:-1 |
935 result sign:-1 |
936 ]. |
936 ]. |
937 ] ifFalse:[ |
937 ] ifFalse:[ |
938 sign < 0 ifTrue:[ |
938 sign < 0 ifTrue:[ |
939 result sign:sign |
939 result sign:sign |
940 ] |
940 ] |
941 ]. |
941 ]. |
942 |
942 |
943 resultDigitByteArray := result digits. |
943 resultDigitByteArray := result digits. |
944 |
944 |
945 carry := 0. |
945 carry := 0. |
948 ok := false. |
948 ok := false. |
949 %{ |
949 %{ |
950 if (__bothSmallInteger(len, val) |
950 if (__bothSmallInteger(len, val) |
951 && __isByteArray(__INST(digitByteArray)) |
951 && __isByteArray(__INST(digitByteArray)) |
952 && __isByteArray(resultDigitByteArray)) { |
952 && __isByteArray(resultDigitByteArray)) { |
953 int _l = __intVal(len); |
953 int _l = __intVal(len); |
954 int _v = __intVal(val); |
954 int _v = __intVal(val); |
955 unsigned _carry = 0; |
955 unsigned _carry = 0; |
956 unsigned _prod; |
956 unsigned _prod; |
957 unsigned char *digitP = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element; |
957 unsigned char *digitP = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element; |
958 unsigned char *resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element; |
958 unsigned char *resultP = __ByteArrayInstPtr(resultDigitByteArray)->ba_element; |
959 |
959 |
960 #if defined(i386) /* XXX actually: LSB_FIRST */ |
960 #if defined(i386) /* XXX actually: LSB_FIRST */ |
961 /* max: 0xFFFF * 0xFFFF -> 0xrFFFE0001 |
961 /* max: 0xFFFF * 0xFFFF -> 0xrFFFE0001 |
962 * + maxCarry (0xFFFF) -> 0xFFFF0000 |
962 * + maxCarry (0xFFFF) -> 0xFFFF0000 |
963 */ |
963 */ |
964 |
964 |
965 if (_v <= 0xFFFF) { |
965 if (_v <= 0xFFFF) { |
966 /* can do it short-wise */ |
966 /* can do it short-wise */ |
967 while (_l > 1) { |
967 while (_l > 1) { |
968 _prod = ((unsigned short *)digitP)[0] * _v + _carry; |
968 _prod = ((unsigned short *)digitP)[0] * _v + _carry; |
969 ((unsigned short *)resultP)[0] = _prod & 0xFFFF; |
969 ((unsigned short *)resultP)[0] = _prod & 0xFFFF; |
970 _carry = _prod >> 16; |
970 _carry = _prod >> 16; |
971 digitP += 2; |
971 digitP += 2; |
972 resultP += 2; |
972 resultP += 2; |
973 _l -= 2; |
973 _l -= 2; |
974 } |
974 } |
975 } |
975 } |
976 #endif |
976 #endif |
977 { |
977 { |
978 while (_l-- > 0) { |
978 while (_l-- > 0) { |
979 _prod = *digitP++ * _v + _carry; |
979 _prod = *digitP++ * _v + _carry; |
980 *resultP++ = _prod & 0xFF; |
980 *resultP++ = _prod & 0xFF; |
981 _carry = _prod >> 8; |
981 _carry = _prod >> 8; |
982 } |
982 } |
983 |
983 |
984 while (_carry) { |
984 while (_carry) { |
985 *resultP++ = _carry & 0xFF; |
985 *resultP++ = _carry & 0xFF; |
986 _carry >>= 8; |
986 _carry >>= 8; |
987 } |
987 } |
988 } |
988 } |
989 ok = true; |
989 ok = true; |
990 } |
990 } |
991 %}. |
991 %}. |
992 " |
992 " |
993 fall back - normally not reached |
993 fall back - normally not reached |
994 (could make it a primitive-failure as well) |
994 (could make it a primitive-failure as well) |
995 " |
995 " |
996 ok ifFalse:[ |
996 ok ifFalse:[ |
997 1 to:len do:[:i | |
997 1 to:len do:[:i | |
998 prod := (digitByteArray basicAt:i) * val + carry. |
998 prod := (digitByteArray basicAt:i) * val + carry. |
999 resultDigitByteArray basicAt:i put:(prod bitAnd:16rFF). |
999 resultDigitByteArray basicAt:i put:(prod bitAnd:16rFF). |
1000 carry := prod bitShift:-8. |
1000 carry := prod bitShift:-8. |
1001 ]. |
1001 ]. |
1002 [carry ~~ 0] whileTrue:[ |
1002 [carry ~~ 0] whileTrue:[ |
1003 len := len + 1. |
1003 len := len + 1. |
1004 resultDigitByteArray basicAt:len put:(carry bitAnd:16rFF). |
1004 resultDigitByteArray basicAt:len put:(carry bitAnd:16rFF). |
1005 carry := carry bitShift:-8 |
1005 carry := carry bitShift:-8 |
1006 ]. |
1006 ]. |
1007 ]. |
1007 ]. |
1008 ^ result compressed |
1008 ^ result compressed |
1009 ! |
1009 ! |
1010 |
1010 |
1011 sumFromInteger:anInteger |
1011 sumFromInteger:anInteger |
1012 "sent, when anInteger does not know how to add the receiver. |
1012 "sent, when anInteger does not know how to add the receiver. |
1013 Return the sum of the receiver and the argument, (which must be a SmallInteger)" |
1013 Return the sum of the receiver and the argument, (which must be a SmallInteger)" |
1014 |
1014 |
1015 anInteger > 0 ifTrue:[ |
1015 anInteger > 0 ifTrue:[ |
1016 sign < 0 ifTrue:[ |
1016 sign < 0 ifTrue:[ |
1017 ^ (self absFastMinus:anInteger) sign:-1 |
1017 ^ (self absFastMinus:anInteger) sign:-1 |
1018 ]. |
1018 ]. |
1019 ^ self absFastPlus:anInteger |
1019 ^ self absFastPlus:anInteger |
1020 ]. |
1020 ]. |
1021 anInteger == 0 ifTrue:[ |
1021 anInteger == 0 ifTrue:[ |
1022 ^ self |
1022 ^ self |
1023 ]. |
1023 ]. |
1024 sign < 0 ifTrue:[ |
1024 sign < 0 ifTrue:[ |
1025 ^ (self absFastPlus:anInteger abs) sign:-1 |
1025 ^ (self absFastPlus:anInteger abs) sign:-1 |
1026 ]. |
1026 ]. |
1027 ^ self absFastMinus:anInteger |
1027 ^ self absFastMinus:anInteger |
1028 |
1028 |
1029 " |
1029 " |
1030 12345678901234567890 |
1030 12345678901234567890 |
1062 quo |
1062 quo |
1063 count "{ Class: SmallInteger }" |
1063 count "{ Class: SmallInteger }" |
1064 digit "{ Class: SmallInteger }" | |
1064 digit "{ Class: SmallInteger }" | |
1065 |
1065 |
1066 anInteger == 0 ifTrue:[ |
1066 anInteger == 0 ifTrue:[ |
1067 ^ DivisionByZeroSignal raise |
1067 ^ DivisionByZeroSignal raise |
1068 ]. |
1068 ]. |
1069 |
1069 |
1070 self = anInteger ifTrue:[ |
1070 self = anInteger ifTrue:[ |
1071 ^ Array with:1 with:0 |
1071 ^ Array with:1 with:0 |
1072 ]. |
1072 ]. |
1073 |
1073 |
1074 tmp1 := self simpleDeepCopy. |
1074 tmp1 := self simpleDeepCopy. |
1075 tmp1 sign:1. |
1075 tmp1 sign:1. |
1076 tmp2 := anInteger simpleDeepCopy. |
1076 tmp2 := anInteger simpleDeepCopy. |
1077 tmp2 sign:1. |
1077 tmp2 sign:1. |
1078 |
1078 |
1079 (tmp1 < tmp2) ifTrue:[ |
1079 (tmp1 < tmp2) ifTrue:[ |
1080 ^ Array with:0 with:tmp1 |
1080 ^ Array with:0 with:tmp1 |
1081 ]. |
1081 ]. |
1082 |
1082 |
1083 count := 0. |
1083 count := 0. |
1084 [tmp2 absLess: tmp1] whileTrue:[ |
1084 [tmp2 absLess: tmp1] whileTrue:[ |
1085 tmp2 mul2. |
1085 tmp2 mul2. |
1086 count := count + 1 |
1086 count := count + 1 |
1087 ]. |
1087 ]. |
1088 |
1088 |
1089 tmp2 div2. |
1089 tmp2 div2. |
1090 |
1090 |
1091 quo := 0 asLargeInteger. |
1091 quo := 0 asLargeInteger. |
1092 quo sign:1. |
1092 quo sign:1. |
1093 |
1093 |
1094 [count == 0] whileFalse:[ |
1094 [count == 0] whileFalse:[ |
1095 quo mul2. |
1095 quo mul2. |
1096 (tmp1 absLess:tmp2) ifFalse:[ |
1096 (tmp1 absLess:tmp2) ifFalse:[ |
1097 quo digits at:1 put:((quo digits at:1) bitOr:1). |
1097 quo digits at:1 put:((quo digits at:1) bitOr:1). |
1098 (tmp1 absSubtract: tmp2) ifFalse:[ |
1098 (tmp1 absSubtract: tmp2) ifFalse:[ |
1099 "/ difference is zero; continue shifting |
1099 "/ difference is zero; continue shifting |
1100 count := count - 1. |
1100 count := count - 1. |
1101 [count >= 8] whileTrue:[ |
1101 [count >= 8] whileTrue:[ |
1102 quo mul256. |
1102 quo mul256. |
1103 count := count - 8 |
1103 count := count - 8 |
1104 ]. |
1104 ]. |
1105 [count == 0] whileFalse:[ |
1105 [count == 0] whileFalse:[ |
1106 quo mul2. |
1106 quo mul2. |
1107 count := count - 1. |
1107 count := count - 1. |
1108 ]. |
1108 ]. |
1109 ^ Array with:quo compressed with:tmp1 compressed |
1109 ^ Array with:quo compressed with:tmp1 compressed |
1110 ]. |
1110 ]. |
1111 ]. |
1111 ]. |
1112 tmp2 div2. |
1112 tmp2 div2. |
1113 count := count - 1 |
1113 count := count - 1 |
1114 ]. |
1114 ]. |
1115 ^ Array with:quo compressed with:tmp1 compressed |
1115 ^ Array with:quo compressed with:tmp1 compressed |
1116 |
1116 |
1117 "Modified: 5.11.1996 / 18:40:24 / cg" |
1117 "Modified: 5.11.1996 / 18:40:24 / cg" |
1118 ! |
1118 ! |
1155 count "{ Class: SmallInteger }" |
1155 count "{ Class: SmallInteger }" |
1156 newDigitByteArray result |
1156 newDigitByteArray result |
1157 ok| |
1157 ok| |
1158 |
1158 |
1159 aPositiveSmallInteger == 0 ifTrue:[ |
1159 aPositiveSmallInteger == 0 ifTrue:[ |
1160 ^ DivisionByZeroSignal raise |
1160 ^ DivisionByZeroSignal raise |
1161 ]. |
1161 ]. |
1162 |
1162 |
1163 "This cannot happen (if always normalized) |
1163 "This cannot happen (if always normalized) |
1164 self < aPositiveSmallInteger ifTrue:[ |
1164 self < aPositiveSmallInteger ifTrue:[ |
1165 ^ Array with:0 with:self |
1165 ^ Array with:0 with:self |
1166 ]. |
1166 ]. |
1167 " |
1167 " |
1168 count := digitByteArray size. |
1168 count := digitByteArray size. |
1169 result := self class basicNew numberOfDigits:count. |
1169 result := self class basicNew numberOfDigits:count. |
1170 newDigitByteArray := result digits. |
1170 newDigitByteArray := result digits. |
1175 __digits = __INST(digitByteArray); |
1175 __digits = __INST(digitByteArray); |
1176 |
1176 |
1177 if (__isByteArray(__digits) |
1177 if (__isByteArray(__digits) |
1178 && __isByteArray(newDigitByteArray) |
1178 && __isByteArray(newDigitByteArray) |
1179 && __bothSmallInteger(count, aPositiveSmallInteger)) { |
1179 && __bothSmallInteger(count, aPositiveSmallInteger)) { |
1180 unsigned int rest = 0; |
1180 unsigned int rest = 0; |
1181 int index = __intVal(count); |
1181 int index = __intVal(count); |
1182 int index0; |
1182 int index0; |
1183 unsigned divisor = __intVal(aPositiveSmallInteger); |
1183 unsigned divisor = __intVal(aPositiveSmallInteger); |
1184 unsigned char *digitBytes = __ByteArrayInstPtr(__digits)->ba_element; |
1184 unsigned char *digitBytes = __ByteArrayInstPtr(__digits)->ba_element; |
1185 unsigned char *resultBytes = __ByteArrayInstPtr(newDigitByteArray)->ba_element; |
1185 unsigned char *resultBytes = __ByteArrayInstPtr(newDigitByteArray)->ba_element; |
1186 |
1186 |
1187 index0 = index; |
1187 index0 = index; |
1188 |
1188 |
1189 /* |
1189 /* |
1190 if (divisor < 0xFFFF) { |
1190 if (divisor < 0xFFFF) { |
1191 while (index > 1) { |
1191 while (index > 1) { |
1192 unsigned int t; |
1192 unsigned int t; |
1193 unsigned div; |
1193 unsigned div; |
1194 |
1194 |
1195 index--; |
1195 index--; |
1196 t = digitBytes[index]; |
1196 t = digitBytes[index]; |
1197 index--; |
1197 index--; |
1198 t = (t << 8) | digitBytes[index]; |
1198 t = (t << 8) | digitBytes[index]; |
1199 t = t | (rest << 16); |
1199 t = t | (rest << 16); |
1200 div = t / divisor; |
1200 div = t / divisor; |
1201 rest = t % divisor; |
1201 rest = t % divisor; |
1202 resultBytes[index+1] = (div >> 8); |
1202 resultBytes[index+1] = (div >> 8); |
1203 resultBytes[index] = (div & 0xFF); |
1203 resultBytes[index] = (div & 0xFF); |
1204 } |
1204 } |
1205 } |
1205 } |
1206 */ |
1206 */ |
1207 while (index > 0) { |
1207 while (index > 0) { |
1208 unsigned int t; |
1208 unsigned int t; |
1209 |
1209 |
1210 index--; |
1210 index--; |
1211 t = digitBytes[index]; |
1211 t = digitBytes[index]; |
1212 t = t | (rest << 8); |
1212 t = t | (rest << 8); |
1213 resultBytes[index] = t / divisor; |
1213 resultBytes[index] = t / divisor; |
1214 rest = t % divisor; |
1214 rest = t % divisor; |
1215 } |
1215 } |
1216 prevRest = __MKSMALLINT(rest); |
1216 prevRest = __MKSMALLINT(rest); |
1217 ok = true; |
1217 ok = true; |
1218 |
1218 |
1219 /* |
1219 /* |
1220 * no need to normalize ? |
1220 * no need to normalize ? |
1221 */ |
1221 */ |
1222 if ((index0 > 4) |
1222 if ((index0 > 4) |
1223 && (resultBytes[index0-1])) { |
1223 && (resultBytes[index0-1])) { |
1224 RETURN ( __ARRAY_WITH2(result, prevRest)); |
1224 RETURN ( __ARRAY_WITH2(result, prevRest)); |
1225 } |
1225 } |
1226 } |
1226 } |
1227 %}. |
1227 %}. |
1228 " |
1228 " |
1229 slow code - not normally reached |
1229 slow code - not normally reached |
1230 (could also do a primitiveFailure here) |
1230 (could also do a primitiveFailure here) |
1231 " |
1231 " |
1232 ok ifFalse:[ |
1232 ok ifFalse:[ |
1233 self primitiveFailed |
1233 self primitiveFailed |
1234 ]. |
1234 ]. |
1235 |
1235 |
1236 ^ Array with:result compressed with:prevRest |
1236 ^ Array with:result compressed with:prevRest |
1237 ! |
1237 ! |
1238 |
1238 |
1253 |
1253 |
1254 index := 1. |
1254 index := 1. |
1255 borrow := aSmallInteger abs. |
1255 borrow := aSmallInteger abs. |
1256 |
1256 |
1257 [borrow ~~ 0] whileTrue:[ |
1257 [borrow ~~ 0] whileTrue:[ |
1258 (index <= len) ifTrue:[ |
1258 (index <= len) ifTrue:[ |
1259 diff := (digitByteArray basicAt:index) - (borrow bitAnd:16rFF). |
1259 diff := (digitByteArray basicAt:index) - (borrow bitAnd:16rFF). |
1260 borrow := borrow bitShift:-8. |
1260 borrow := borrow bitShift:-8. |
1261 diff < 0 ifTrue:[ |
1261 diff < 0 ifTrue:[ |
1262 diff := diff + 256. |
1262 diff := diff + 256. |
1263 borrow := borrow + 1. |
1263 borrow := borrow + 1. |
1264 ] |
1264 ] |
1265 ] ifFalse:[ |
1265 ] ifFalse:[ |
1266 diff := borrow bitAnd:255. |
1266 diff := borrow bitAnd:255. |
1267 borrow := borrow bitShift:-8. |
1267 borrow := borrow bitShift:-8. |
1268 ]. |
1268 ]. |
1269 resultDigitByteArray basicAt:index put:(lastDigit := diff). |
1269 resultDigitByteArray basicAt:index put:(lastDigit := diff). |
1270 index := index + 1 |
1270 index := index + 1 |
1271 ]. |
1271 ]. |
1272 [index <= len] whileTrue:[ |
1272 [index <= len] whileTrue:[ |
1273 resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index). |
1273 resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index). |
1274 index := index + 1 |
1274 index := index + 1 |
1275 ]. |
1275 ]. |
1276 |
1276 |
1277 lastDigit == 0 ifTrue:[ |
1277 lastDigit == 0 ifTrue:[ |
1278 ^ result compressed |
1278 ^ result compressed |
1279 ]. |
1279 ]. |
1280 ^ result |
1280 ^ result |
1281 |
1281 |
1282 " |
1282 " |
1283 12345678900000000000 absFastMinus:1 |
1283 12345678900000000000 absFastMinus:1 |
1306 |
1306 |
1307 index := 1. |
1307 index := 1. |
1308 carry := aSmallInteger abs. |
1308 carry := aSmallInteger abs. |
1309 |
1309 |
1310 [carry ~~ 0] whileTrue:[ |
1310 [carry ~~ 0] whileTrue:[ |
1311 (index <= len) ifTrue:[ |
1311 (index <= len) ifTrue:[ |
1312 carry := (digitByteArray basicAt:index) + carry. |
1312 carry := (digitByteArray basicAt:index) + carry. |
1313 ]. |
1313 ]. |
1314 resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF). |
1314 resultDigitByteArray basicAt:index put:(lastDigit := carry bitAnd:16rFF). |
1315 carry := carry bitShift:-8. |
1315 carry := carry bitShift:-8. |
1316 index := index + 1 |
1316 index := index + 1 |
1317 ]. |
1317 ]. |
1318 [index <= len] whileTrue:[ |
1318 [index <= len] whileTrue:[ |
1319 resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index). |
1319 resultDigitByteArray basicAt:index put:(lastDigit := digitByteArray basicAt:index). |
1320 index := index + 1 |
1320 index := index + 1 |
1321 ]. |
1321 ]. |
1322 |
1322 |
1323 lastDigit == 0 ifTrue:[ |
1323 lastDigit == 0 ifTrue:[ |
1324 ^ result compressed |
1324 ^ result compressed |
1325 ]. |
1325 ]. |
1326 ^ result |
1326 ^ result |
1327 |
1327 |
1328 "Modified: 5.11.1996 / 14:09:19 / cg" |
1328 "Modified: 5.11.1996 / 14:09:19 / cg" |
1329 ! |
1329 ! |
1341 myLen := digitByteArray size. |
1341 myLen := digitByteArray size. |
1342 otherDigitByteArray := aLargeInteger digits. |
1342 otherDigitByteArray := aLargeInteger digits. |
1343 otherLen := otherDigitByteArray size. |
1343 otherLen := otherDigitByteArray size. |
1344 |
1344 |
1345 [(digitByteArray basicAt:myLen) == 0] whileTrue:[ |
1345 [(digitByteArray basicAt:myLen) == 0] whileTrue:[ |
1346 myLen := myLen - 1 |
1346 myLen := myLen - 1 |
1347 ]. |
1347 ]. |
1348 [(otherDigitByteArray basicAt:otherLen) == 0] whileTrue:[ |
1348 [(otherDigitByteArray basicAt:otherLen) == 0] whileTrue:[ |
1349 otherLen := otherLen - 1 |
1349 otherLen := otherLen - 1 |
1350 ]. |
1350 ]. |
1351 (myLen < otherLen) ifTrue:[^ true]. |
1351 (myLen < otherLen) ifTrue:[^ true]. |
1352 (myLen > otherLen) ifTrue:[^ false]. |
1352 (myLen > otherLen) ifTrue:[^ false]. |
1353 |
1353 |
1354 [myLen > 0] whileTrue:[ |
1354 [myLen > 0] whileTrue:[ |
1355 d1 := digitByteArray basicAt:myLen. |
1355 d1 := digitByteArray basicAt:myLen. |
1356 d2 := otherDigitByteArray basicAt:myLen. |
1356 d2 := otherDigitByteArray basicAt:myLen. |
1357 d1 == d2 ifFalse:[ |
1357 d1 == d2 ifFalse:[ |
1358 (d1 < d2) ifTrue:[^ true]. |
1358 (d1 < d2) ifTrue:[^ true]. |
1359 ^ false |
1359 ^ false |
1360 ]. |
1360 ]. |
1361 myLen := myLen - 1 |
1361 myLen := myLen - 1 |
1362 ]. |
1362 ]. |
1363 ^ false |
1363 ^ false |
1364 |
1364 |
1365 "Modified: 5.11.1996 / 18:37:27 / cg" |
1365 "Modified: 5.11.1996 / 18:37:27 / cg" |
1366 ! |
1366 ! |
1389 index := 1. |
1389 index := 1. |
1390 borrow := 0. |
1390 borrow := 0. |
1391 |
1391 |
1392 done := false. |
1392 done := false. |
1393 [done] whileFalse:[ |
1393 [done] whileFalse:[ |
1394 diff := borrow. |
1394 diff := borrow. |
1395 (index <= len1) ifTrue:[ |
1395 (index <= len1) ifTrue:[ |
1396 diff := diff + (digitByteArray basicAt:index). |
1396 diff := diff + (digitByteArray basicAt:index). |
1397 (index <= len2) ifTrue:[ |
1397 (index <= len2) ifTrue:[ |
1398 diff := diff - (otherDigitByteArray basicAt:index) |
1398 diff := diff - (otherDigitByteArray basicAt:index) |
1399 ] |
1399 ] |
1400 ] ifFalse:[ |
1400 ] ifFalse:[ |
1401 (index <= len2) ifTrue:[ |
1401 (index <= len2) ifTrue:[ |
1402 diff := diff - (otherDigitByteArray basicAt:index) |
1402 diff := diff - (otherDigitByteArray basicAt:index) |
1403 ] ifFalse:[ |
1403 ] ifFalse:[ |
1404 "end reached" |
1404 "end reached" |
1405 done := true |
1405 done := true |
1406 ] |
1406 ] |
1407 ]. |
1407 ]. |
1408 |
1408 |
1409 "/ workaround for |
1409 "/ workaround for |
1410 "/ gcc code generator bug |
1410 "/ gcc code generator bug |
1411 |
1411 |
1412 (diff >= 0) ifTrue:[ |
1412 (diff >= 0) ifTrue:[ |
1413 borrow := 0 |
1413 borrow := 0 |
1414 ] ifFalse:[ |
1414 ] ifFalse:[ |
1415 borrow := -1. |
1415 borrow := -1. |
1416 diff := diff + 16r100 |
1416 diff := diff + 16r100 |
1417 ]. |
1417 ]. |
1418 |
1418 |
1419 "/ (diff < 0) ifTrue:[ |
1419 "/ (diff < 0) ifTrue:[ |
1420 "/ borrow := -1. |
1420 "/ borrow := -1. |
1421 "/ diff := diff + 16r100 |
1421 "/ diff := diff + 16r100 |
1422 "/ ] ifFalse:[ |
1422 "/ ] ifFalse:[ |
1423 "/ borrow := 0 |
1423 "/ borrow := 0 |
1424 "/ ]. |
1424 "/ ]. |
1425 |
1425 |
1426 resultDigitByteArray basicAt:index put:diff. |
1426 resultDigitByteArray basicAt:index put:diff. |
1427 index := index + 1 |
1427 index := index + 1 |
1428 ]. |
1428 ]. |
1429 |
1429 |
1430 (borrow ~~ 0) ifTrue:[ |
1430 (borrow ~~ 0) ifTrue:[ |
1431 "/ must generate 255's complement |
1431 "/ must generate 255's complement |
1432 |
1432 |
1433 result sign:-1. |
1433 result sign:-1. |
1434 [index <= lResult] whileTrue:[ |
1434 [index <= lResult] whileTrue:[ |
1435 resultDigitByteArray basicAt:index put:16rFF. |
1435 resultDigitByteArray basicAt:index put:16rFF. |
1436 index := index + 1. |
1436 index := index + 1. |
1437 ]. |
1437 ]. |
1438 index := resultDigitByteArray size. |
1438 index := resultDigitByteArray size. |
1439 [index > 0] whileTrue:[ |
1439 [index > 0] whileTrue:[ |
1440 resultDigitByteArray basicAt:index put:(255 - (resultDigitByteArray at:index)). |
1440 resultDigitByteArray basicAt:index put:(255 - (resultDigitByteArray at:index)). |
1441 index := index -1. |
1441 index := index -1. |
1442 ]. |
1442 ]. |
1443 |
1443 |
1444 index := 1. |
1444 index := 1. |
1445 carry := 1. |
1445 carry := 1. |
1446 [carry ~~ 0] whileTrue:[ |
1446 [carry ~~ 0] whileTrue:[ |
1447 (index <= lResult) ifTrue:[ |
1447 (index <= lResult) ifTrue:[ |
1448 carry := (resultDigitByteArray basicAt:index) + carry. |
1448 carry := (resultDigitByteArray basicAt:index) + carry. |
1449 ]. |
1449 ]. |
1450 resultDigitByteArray basicAt:index put:(carry bitAnd:16rFF). |
1450 resultDigitByteArray basicAt:index put:(carry bitAnd:16rFF). |
1451 carry := carry bitShift:-8. |
1451 carry := carry bitShift:-8. |
1452 index := index + 1 |
1452 index := index + 1 |
1453 ]. |
1453 ]. |
1454 ]. |
1454 ]. |
1455 ^ result compressed |
1455 ^ result compressed |
1456 |
1456 |
1457 "Modified: 5.11.1996 / 14:09:25 / cg" |
1457 "Modified: 5.11.1996 / 14:09:25 / cg" |
1458 ! |
1458 ! |
1479 %{ |
1479 %{ |
1480 if (__isByteArray(__INST(digitByteArray)) |
1480 if (__isByteArray(__INST(digitByteArray)) |
1481 && __isByteArray(otherDigitByteArray) |
1481 && __isByteArray(otherDigitByteArray) |
1482 && __isByteArray(resultDigitByteArray) |
1482 && __isByteArray(resultDigitByteArray) |
1483 && __bothSmallInteger(len1, len2)) { |
1483 && __bothSmallInteger(len1, len2)) { |
1484 unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element; |
1484 unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element; |
1485 unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element; |
1485 unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element; |
1486 unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element; |
1486 unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element; |
1487 int _index1, _index2, _dstIndex, _idx; |
1487 int _index1, _index2, _dstIndex, _idx; |
1488 unsigned _prod, _carry, _v; |
1488 unsigned _prod, _carry, _v; |
1489 |
1489 |
1490 for (_index1 = 0; _index1 < __intVal(len1); _index1++) { |
1490 for (_index1 = 0; _index1 < __intVal(len1); _index1++) { |
1491 for (_index2 = 0; _index2 < __intVal(len2); _index2++) { |
1491 for (_index2 = 0; _index2 < __intVal(len2); _index2++) { |
1492 _dstIndex = _index1 + _index2; |
1492 _dstIndex = _index1 + _index2; |
1493 _prod = myBytes[_index1] * otherBytes[_index2]; |
1493 _prod = myBytes[_index1] * otherBytes[_index2]; |
1494 _prod += resultBytes[_dstIndex]; |
1494 _prod += resultBytes[_dstIndex]; |
1495 resultBytes[_dstIndex] = _prod & 0xFF; |
1495 resultBytes[_dstIndex] = _prod & 0xFF; |
1496 _carry = _prod >> 8; |
1496 _carry = _prod >> 8; |
1497 if (_carry) { |
1497 if (_carry) { |
1498 _idx = _dstIndex + 1; |
1498 _idx = _dstIndex + 1; |
1499 while (_carry) { |
1499 while (_carry) { |
1500 _v = resultBytes[_idx] + _carry; |
1500 _v = resultBytes[_idx] + _carry; |
1501 resultBytes[_idx] = _v & 0xFF; |
1501 resultBytes[_idx] = _v & 0xFF; |
1502 _carry = _v >> 8; |
1502 _carry = _v >> 8; |
1503 _idx = _idx + 1; |
1503 _idx = _idx + 1; |
1504 } |
1504 } |
1505 } |
1505 } |
1506 } |
1506 } |
1507 } |
1507 } |
1508 ok = true; |
1508 ok = true; |
1509 } |
1509 } |
1510 %}. |
1510 %}. |
1511 ok ifFalse:[ |
1511 ok ifFalse:[ |
1512 1 to:len1 do:[:index1 | |
1512 1 to:len1 do:[:index1 | |
1513 1 to:len2 do:[:index2 | |
1513 1 to:len2 do:[:index2 | |
1514 dstIndex := index1 + index2 - 1. |
1514 dstIndex := index1 + index2 - 1. |
1515 prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2). |
1515 prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2). |
1516 prod := prod + (resultDigitByteArray basicAt:dstIndex). |
1516 prod := prod + (resultDigitByteArray basicAt:dstIndex). |
1517 resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF). |
1517 resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF). |
1518 carry := prod bitShift:-8. |
1518 carry := prod bitShift:-8. |
1519 carry ~~ 0 ifTrue:[ |
1519 carry ~~ 0 ifTrue:[ |
1520 idx := dstIndex + 1. |
1520 idx := dstIndex + 1. |
1521 [carry ~~ 0] whileTrue:[ |
1521 [carry ~~ 0] whileTrue:[ |
1522 v := (resultDigitByteArray basicAt:idx) + carry. |
1522 v := (resultDigitByteArray basicAt:idx) + carry. |
1523 resultDigitByteArray basicAt:idx put:(v bitAnd:255). |
1523 resultDigitByteArray basicAt:idx put:(v bitAnd:255). |
1524 carry := v bitShift:-8. |
1524 carry := v bitShift:-8. |
1525 idx := idx + 1 |
1525 idx := idx + 1 |
1526 ] |
1526 ] |
1527 ] |
1527 ] |
1528 ] |
1528 ] |
1529 ]. |
1529 ]. |
1530 ]. |
1530 ]. |
1531 ^ result compressed |
1531 ^ result compressed |
1532 ! |
1532 ! |
1533 |
1533 |
1534 absPlus:aLargeInteger |
1534 absPlus:aLargeInteger |
1551 index := 1. |
1551 index := 1. |
1552 carry := 0. |
1552 carry := 0. |
1553 |
1553 |
1554 done := false. |
1554 done := false. |
1555 [done] whileFalse:[ |
1555 [done] whileFalse:[ |
1556 sum := carry. |
1556 sum := carry. |
1557 (index <= len1) ifTrue:[ |
1557 (index <= len1) ifTrue:[ |
1558 sum := sum + (digitByteArray basicAt:index). |
1558 sum := sum + (digitByteArray basicAt:index). |
1559 (index <= len2) ifTrue:[ |
1559 (index <= len2) ifTrue:[ |
1560 sum := sum + (otherDigitByteArray basicAt:index) |
1560 sum := sum + (otherDigitByteArray basicAt:index) |
1561 ] |
1561 ] |
1562 ] ifFalse:[ |
1562 ] ifFalse:[ |
1563 (index <= len2) ifTrue:[ |
1563 (index <= len2) ifTrue:[ |
1564 sum := sum + (otherDigitByteArray basicAt:index) |
1564 sum := sum + (otherDigitByteArray basicAt:index) |
1565 ] ifFalse:[ |
1565 ] ifFalse:[ |
1566 "end reached" |
1566 "end reached" |
1567 done := true |
1567 done := true |
1568 ] |
1568 ] |
1569 ]. |
1569 ]. |
1570 (sum >= 16r100) ifTrue:[ |
1570 (sum >= 16r100) ifTrue:[ |
1571 carry := 1. |
1571 carry := 1. |
1572 sum := sum - 16r100 |
1572 sum := sum - 16r100 |
1573 ] ifFalse:[ |
1573 ] ifFalse:[ |
1574 carry := 0 |
1574 carry := 0 |
1575 ]. |
1575 ]. |
1576 resultDigitByteArray basicAt:index put:sum. |
1576 resultDigitByteArray basicAt:index put:sum. |
1577 index := index + 1 |
1577 index := index + 1 |
1578 ]. |
1578 ]. |
1579 ^ result compressed |
1579 ^ result compressed |
1580 |
1580 |
1581 "Modified: 5.11.1996 / 14:09:34 / cg" |
1581 "Modified: 5.11.1996 / 14:09:34 / cg" |
1582 ! |
1582 ! |
1599 |
1599 |
1600 len1 := digitByteArray size. |
1600 len1 := digitByteArray size. |
1601 otherDigitByteArray := aLargeInteger digits. |
1601 otherDigitByteArray := aLargeInteger digits. |
1602 len2 := otherDigitByteArray size. |
1602 len2 := otherDigitByteArray size. |
1603 len2 > len1 ifTrue:[ |
1603 len2 > len1 ifTrue:[ |
1604 [(otherDigitByteArray at:len2) == 0] whileTrue:[ |
1604 [(otherDigitByteArray at:len2) == 0] whileTrue:[ |
1605 len2 := len2 - 1 |
1605 len2 := len2 - 1 |
1606 ]. |
1606 ]. |
1607 len2 > len1 ifTrue:[ |
1607 len2 > len1 ifTrue:[ |
1608 self halt "/ may not be called that way |
1608 self halt "/ may not be called that way |
1609 ]. |
1609 ]. |
1610 ]. |
1610 ]. |
1611 |
1611 |
1612 nonZero := false. |
1612 nonZero := false. |
1613 index := 1. |
1613 index := 1. |
1614 borrow := 0. |
1614 borrow := 0. |
1615 |
1615 |
1616 done := false. |
1616 done := false. |
1617 [index <= len1] whileTrue:[ |
1617 [index <= len1] whileTrue:[ |
1618 diff := borrow. |
1618 diff := borrow. |
1619 diff := diff + (digitByteArray basicAt:index). |
1619 diff := diff + (digitByteArray basicAt:index). |
1620 index <= len2 ifTrue:[ |
1620 index <= len2 ifTrue:[ |
1621 diff := diff - (otherDigitByteArray basicAt:index). |
1621 diff := diff - (otherDigitByteArray basicAt:index). |
1622 ]. |
1622 ]. |
1623 |
1623 |
1624 "/ workaround for |
1624 "/ workaround for |
1625 "/ gcc code generator bug |
1625 "/ gcc code generator bug |
1626 |
1626 |
1627 (diff >= 0) ifTrue:[ |
1627 (diff >= 0) ifTrue:[ |
1628 borrow := 0 |
1628 borrow := 0 |
1629 ] ifFalse:[ |
1629 ] ifFalse:[ |
1630 borrow := -1. |
1630 borrow := -1. |
1631 diff := diff + 16r100 |
1631 diff := diff + 16r100 |
1632 ]. |
1632 ]. |
1633 diff ~~ 0 ifTrue:[ |
1633 diff ~~ 0 ifTrue:[ |
1634 nonZero := true |
1634 nonZero := true |
1635 ]. |
1635 ]. |
1636 digitByteArray basicAt:index put:diff. |
1636 digitByteArray basicAt:index put:diff. |
1637 index := index + 1 |
1637 index := index + 1 |
1638 ]. |
1638 ]. |
1639 ^ nonZero |
1639 ^ nonZero |
1640 |
1640 |
1641 "Created: 5.11.1996 / 16:23:47 / cg" |
1641 "Created: 5.11.1996 / 16:23:47 / cg" |
1642 "Modified: 5.11.1996 / 18:56:50 / cg" |
1642 "Modified: 5.11.1996 / 18:56:50 / cg" |
1649 |
1649 |
1650 %{ /* NOCONTEXT */ |
1650 %{ /* NOCONTEXT */ |
1651 OBJ __digits = __INST(digitByteArray); |
1651 OBJ __digits = __INST(digitByteArray); |
1652 |
1652 |
1653 if (__isByteArray(__digits)) { |
1653 if (__isByteArray(__digits)) { |
1654 int __nBytes = __byteArraySize(__digits); |
1654 int __nBytes = __byteArraySize(__digits); |
1655 unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element; |
1655 unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element; |
1656 unsigned __this, __next; |
1656 unsigned __this, __next; |
1657 int __idx; |
1657 int __idx; |
1658 |
1658 |
1659 if (__nBytes == 1) { |
1659 if (__nBytes == 1) { |
1660 __bp[0] >>= 1; |
1660 __bp[0] >>= 1; |
1661 RETURN (self); |
1661 RETURN (self); |
1662 } |
1662 } |
1663 |
1663 |
1664 __idx = 1; |
1664 __idx = 1; |
1665 |
1665 |
1666 if ((__idx+4) < __nBytes) { |
1666 if ((__idx+4) < __nBytes) { |
1667 __this = ((unsigned long *)__bp)[0]; |
1667 __this = ((unsigned long *)__bp)[0]; |
1668 |
1668 |
1669 while ((__idx+4) < __nBytes) { |
1669 while ((__idx+4) < __nBytes) { |
1670 __next = ((unsigned long *)__bp)[1]; |
1670 __next = ((unsigned long *)__bp)[1]; |
1671 __this >>= 1; |
1671 __this >>= 1; |
1672 __this |= __next << 31; |
1672 __this |= __next << 31; |
1673 ((unsigned long *)__bp)[0] = __this; |
1673 ((unsigned long *)__bp)[0] = __this; |
1674 __this = __next; |
1674 __this = __next; |
1675 __bp += 4; |
1675 __bp += 4; |
1676 __idx += 4; |
1676 __idx += 4; |
1677 } |
1677 } |
1678 } |
1678 } |
1679 |
1679 |
1680 __this = __bp[0]; |
1680 __this = __bp[0]; |
1681 while (__idx < __nBytes) { |
1681 while (__idx < __nBytes) { |
1682 __next = __bp[1]; |
1682 __next = __bp[1]; |
1683 __this >>= 1; |
1683 __this >>= 1; |
1684 __this |= __next << 7; |
1684 __this |= __next << 7; |
1685 __bp[0] = __this; |
1685 __bp[0] = __this; |
1686 __this = __next; |
1686 __this = __next; |
1687 __bp++; |
1687 __bp++; |
1688 __idx++; |
1688 __idx++; |
1689 } |
1689 } |
1690 __bp[0] = __this >> 1; |
1690 __bp[0] = __this >> 1; |
1691 RETURN (self); |
1691 RETURN (self); |
1692 } |
1692 } |
1693 %}. |
1693 %}. |
1694 self primitiveFailed |
1694 self primitiveFailed |
1695 |
1695 |
1696 " |
1696 " |
1711 |
1711 |
1712 nBytes := digitByteArray size. |
1712 nBytes := digitByteArray size. |
1713 |
1713 |
1714 b := digitByteArray at:nBytes. |
1714 b := digitByteArray at:nBytes. |
1715 (b bitAnd:16r80) ~~ 0 ifTrue:[ |
1715 (b bitAnd:16r80) ~~ 0 ifTrue:[ |
1716 "/ need another byte |
1716 "/ need another byte |
1717 nBytes := nBytes + 1. |
1717 nBytes := nBytes + 1. |
1718 t := ByteArray uninitializedNew:nBytes. |
1718 t := ByteArray uninitializedNew:nBytes. |
1719 t replaceFrom:1 with:digitByteArray. |
1719 t replaceFrom:1 with:digitByteArray startingAt:1. |
1720 t at:nBytes put:0. |
1720 t at:nBytes put:0. |
1721 digitByteArray := t. |
1721 digitByteArray := t. |
1722 ]. |
1722 ]. |
1723 |
1723 |
1724 %{ |
1724 %{ |
1725 OBJ __digits = __INST(digitByteArray); |
1725 OBJ __digits = __INST(digitByteArray); |
1726 |
1726 |
1727 if (__isByteArray(__digits)) { |
1727 if (__isByteArray(__digits)) { |
1728 int __nBytes = __intVal(nBytes); |
1728 int __nBytes = __intVal(nBytes); |
1729 unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element; |
1729 unsigned char *__bp = __ByteArrayInstPtr(__digits)->ba_element; |
1730 unsigned __carry = 0, __newCarry, __this; |
1730 unsigned __carry = 0, __newCarry, __this; |
1731 int __idx; |
1731 int __idx; |
1732 |
1732 |
1733 while (__nBytes >= 4) { |
1733 while (__nBytes >= 4) { |
1734 __this = ((unsigned long *)__bp)[0]; |
1734 __this = ((unsigned long *)__bp)[0]; |
1735 __newCarry = __this >> 31; |
1735 __newCarry = __this >> 31; |
1736 ((unsigned long *)__bp)[0] = (__this << 1) | __carry; |
1736 ((unsigned long *)__bp)[0] = (__this << 1) | __carry; |
1737 __carry = __newCarry; |
1737 __carry = __newCarry; |
1738 __bp += 4; |
1738 __bp += 4; |
1739 __nBytes -= 4; |
1739 __nBytes -= 4; |
1740 } |
1740 } |
1741 while (__nBytes) { |
1741 while (__nBytes) { |
1742 __this = __bp[0]; |
1742 __this = __bp[0]; |
1743 __newCarry = __this >> 7; |
1743 __newCarry = __this >> 7; |
1744 __bp[0] = (__this << 1) | __carry; |
1744 __bp[0] = (__this << 1) | __carry; |
1745 __carry = __newCarry; |
1745 __carry = __newCarry; |
1746 __bp ++; |
1746 __bp ++; |
1747 __nBytes--; |
1747 __nBytes--; |
1748 } |
1748 } |
1749 RETURN (self); |
1749 RETURN (self); |
1750 } |
1750 } |
1751 %}. |
1751 %}. |
1752 self primitiveFailed |
1752 self primitiveFailed |
1753 |
1753 |
1754 " |
1754 " |