251 "this is a q&d hack - we loose lots of precision here ..." |
251 "this is a q&d hack - we loose lots of precision here ..." |
252 ^ (self asFloat / aNumber asFloat) |
252 ^ (self asFloat / aNumber asFloat) |
253 ! |
253 ! |
254 |
254 |
255 // aNumber |
255 // aNumber |
256 "return the quotient of the receiver and the argument, aNumber" |
256 "return the quotient of the receiver and the argument, aNumber. |
257 |
257 The result is truncated toward negative infinity and negative, |
258 |otherSign divMod d rem abs "{ Class: SmallInteger }" | |
258 if the operands signs differ." |
|
259 |
|
260 |otherSign divMod d rem abs "{ Class: SmallInteger }" n| |
259 |
261 |
260 otherSign := aNumber sign. |
262 otherSign := aNumber sign. |
261 |
263 |
262 " |
264 " |
263 this is the common case, dividing by a SmallInteger. |
265 this is the common case, dividing by a SmallInteger. |
274 "/ stupid adjust ... |
276 "/ stupid adjust ... |
275 (divMod at:2) == 0 ifFalse:[ |
277 (divMod at:2) == 0 ifFalse:[ |
276 ^ (rem sign:-1) - 1 |
278 ^ (rem sign:-1) - 1 |
277 ]. |
279 ]. |
278 ^ rem sign:-1 |
280 ^ rem sign:-1 |
279 ] |
281 ]. |
|
282 n := aNumber asLargeInteger. |
|
283 ] ifFalse:[ |
|
284 n := aNumber |
280 ]. |
285 ]. |
281 |
286 |
282 " |
287 " |
283 if the argument is not a largeInteger, coerce |
288 if the argument is not a largeInteger, coerce |
284 " |
289 " |
285 (aNumber class == self class) ifFalse:[ |
290 (n class == self class) ifFalse:[ |
286 ^ self retry:#// coercing:aNumber |
291 ^ self retry:#// coercing:aNumber |
287 ]. |
292 ]. |
288 |
293 |
289 sign < 0 ifTrue:[ |
294 sign < 0 ifTrue:[ |
290 (sign == otherSign) ifTrue:[^ (self absDiv:aNumber negated) at:1]. |
295 (sign == otherSign) ifTrue:[^ (self absDiv:n negated) at:1]. |
291 ] ifFalse:[ |
296 ] ifFalse:[ |
292 (sign == otherSign) ifTrue:[^ (self absDiv:aNumber) at:1]. |
297 (sign == otherSign) ifTrue:[^ (self absDiv:n) at:1]. |
293 ]. |
298 ]. |
294 |
299 |
295 divMod := self absDiv:aNumber. |
300 divMod := self absDiv:n. |
296 "/ stupid adjust ... |
301 "/ stupid adjust ... |
297 (divMod at:2) == 0 ifFalse:[ |
302 (divMod at:2) == 0 ifFalse:[ |
298 ^ ((divMod at:1) sign:-1) - 1 |
303 ^ ((divMod at:1) sign:-1) - 1 |
299 ]. |
304 ]. |
300 ^ (divMod at:1) sign:-1 |
305 ^ (divMod at:1) sign:-1 |
301 |
306 |
302 " |
307 " |
303 9000000000 // 4000000000 => 2 |
308 900 // 400 |
304 -9000000000 // 4000000000 => -3 |
309 -900 // 400 |
305 9000000000 // -4000000000 => -3 |
310 900 // -400 |
306 -9000000000 // -4000000000 => 2 |
311 -900 // -400 |
307 |
312 |
308 9000000000 quo: 4000000000 => 2 |
313 9000000000 // 4000000000 |
309 -9000000000 quo: 4000000000 => -2 |
314 -9000000000 // 4000000000 |
310 9000000000 quo: -4000000000 => -2 |
315 9000000000 // -4000000000 |
311 -9000000000 quo: -4000000000 => 2 |
316 -9000000000 // -4000000000 |
312 " |
317 |
313 |
318 900 quo: 400 |
314 "Modified: 29.10.1996 / 20:44:23 / cg" |
319 -900 quo: 400 |
|
320 900 quo: -400 |
|
321 -900 quo: -400 |
|
322 |
|
323 9000000000 quo: 4000000000 |
|
324 -9000000000 quo: 4000000000 |
|
325 9000000000 quo: -4000000000 |
|
326 -9000000000 quo: -4000000000 |
|
327 " |
|
328 |
|
329 "Modified: 5.11.1996 / 14:16:46 / cg" |
315 ! |
330 ! |
316 |
331 |
317 \\ aNumber |
332 \\ aNumber |
318 "return the remainder of division of the receiver by the argument, aNumber" |
333 "return the remainder of division of the receiver by the argument, aNumber. |
319 |
334 The sign of the result is that of aNumber." |
320 |abs| |
335 |
|
336 |abs rem| |
321 |
337 |
322 abs := aNumber abs. |
338 abs := aNumber abs. |
323 |
339 |
324 " |
340 " |
325 this is the common case, dividing by a SmallInteger. |
341 this is the common case, dividing by a SmallInteger. |
326 Use a special method for this case ... |
342 Use a special method for this case ... |
327 " |
343 " |
328 (aNumber class == SmallInteger) ifTrue:[ |
344 (aNumber class == SmallInteger) ifTrue:[ |
329 (abs between:1 and:16r003fffff) ifTrue:[ |
345 (abs between:1 and:16r003fffff) ifTrue:[ |
330 ^ ((self absFastDiv:abs) at:2) |
346 rem := (self absFastDiv:abs) at:2. |
331 ] |
347 ] ifFalse:[ |
332 ]. |
348 rem := (self absDiv:abs asLargeInteger) at:2 |
333 |
349 ]. |
334 " |
350 ] ifFalse:[ |
335 if the argument is not a largeInteger, coerce |
351 " |
336 " |
352 if the argument is not a largeInteger, coerce |
337 (aNumber class == self class) ifFalse:[ |
353 " |
338 ^ self retry:#\\ coercing:aNumber |
354 (aNumber class == self class) ifFalse:[ |
339 ]. |
355 ^ self retry:#\\ coercing:aNumber |
340 |
356 ]. |
341 ^ ((self absDiv:abs) at:2) |
357 |
342 |
358 rem := (self absDiv:abs) at:2. |
343 " |
359 ]. |
344 9000000000 \\ 4000000000 => 1000000000 |
360 |
345 -9000000000 \\ 4000000000 => 1000000000 |
361 aNumber negative ifTrue:[ |
346 9000000000 \\ -4000000000 => 1000000000 |
362 ^ rem negated |
347 -9000000000 \\ -4000000000 => 1000000000 |
363 ]. |
348 |
364 ^ rem |
349 9000000000 rem: 4000000000 => 1000000000 |
365 |
350 -9000000000 rem: 4000000000 => -1000000000 |
366 " |
351 9000000000 rem: -4000000000 => -1000000000 |
367 900 \\ 400 |
352 -9000000000 rem: -4000000000 => 1000000000 |
368 -900 \\ 400 |
353 " |
369 900 \\ -400 |
354 |
370 -900 \\ -400 |
355 "Modified: 29.10.1996 / 20:41:35 / cg" |
371 |
|
372 9000000000 \\ 4000000000 |
|
373 -9000000000 \\ 4000000000 |
|
374 9000000000 \\ -4000000000 |
|
375 -9000000000 \\ -4000000000 |
|
376 |
|
377 900 rem: 400 |
|
378 -900 rem: 400 |
|
379 900 rem: -400 |
|
380 -900 rem: -400 |
|
381 |
|
382 9000000000 rem: 4000000000 |
|
383 -9000000000 rem: 4000000000 |
|
384 9000000000 rem: -4000000000 |
|
385 -9000000000 rem: -4000000000 |
|
386 " |
|
387 |
|
388 "Modified: 5.11.1996 / 13:54:32 / cg" |
356 ! |
389 ! |
357 |
390 |
358 divMod:aNumber |
391 divMod:aNumber |
359 "return an array filled with self // aNumber and |
392 "return an array filled with self // aNumber and |
360 self \\ aNumber. |
393 self \\ aNumber. |
454 (sign == otherSign) ifTrue:[^ (self absDiv:aNumber) at:1]. |
491 (sign == otherSign) ifTrue:[^ (self absDiv:aNumber) at:1]. |
455 ]. |
492 ]. |
456 ^ ((self absDiv:aNumber) at:1) sign:-1 |
493 ^ ((self absDiv:aNumber) at:1) sign:-1 |
457 |
494 |
458 " |
495 " |
459 9000000000 // 4000000000 => 2 |
496 900 // 400 |
460 -9000000000 // 4000000000 => -3 |
497 -900 // 400 |
461 9000000000 // -4000000000 => -3 |
498 900 // -400 |
462 -9000000000 // -4000000000 => 2 |
499 -900 // -400 |
463 |
500 |
464 9000000000 quo: 4000000000 => 2 |
501 9000000000 // 4000000000 |
465 -9000000000 quo: 4000000000 => -2 |
502 -9000000000 // 4000000000 |
466 9000000000 quo: -4000000000 => -2 |
503 9000000000 // -4000000000 |
467 -9000000000 quo: -4000000000 => 2 |
504 -9000000000 // -4000000000 |
468 " |
505 |
469 |
506 900 quo: 400 |
470 "Modified: 29.10.1996 / 20:39:09 / cg" |
507 -900 quo: 400 |
|
508 900 quo: -400 |
|
509 -900 quo: -400 |
|
510 |
|
511 9000000000 quo: 4000000000 |
|
512 -9000000000 quo: 4000000000 |
|
513 9000000000 quo: -4000000000 |
|
514 -9000000000 quo: -4000000000 |
|
515 " |
|
516 |
|
517 "Modified: 5.11.1996 / 14:14:17 / cg" |
471 ! |
518 ! |
472 |
519 |
473 rem:aNumber |
520 rem:aNumber |
474 "return the remainder of division of the receiver by the argument, aNumber" |
521 "return the remainder of division of the receiver by the argument, aNumber. |
475 |
522 The returned remainder has the same sign as the receiver." |
476 |otherSign rem abs "{ Class: SmallInteger }" | |
523 |
477 |
524 |rem abs "{ Class: SmallInteger }" | |
478 otherSign := aNumber sign. |
|
479 |
525 |
480 " |
526 " |
481 this is the common case, dividing by a SmallInteger. |
527 this is the common case, dividing by a SmallInteger. |
482 Use a special method for this case ... |
528 Use special code for this case ... |
483 " |
529 " |
484 (aNumber class == SmallInteger) ifTrue:[ |
530 (aNumber class == SmallInteger) ifTrue:[ |
485 abs := aNumber. |
531 abs := aNumber. |
486 abs := abs abs. |
532 abs := abs abs. |
487 (abs between:1 and:16r003fffff) ifTrue:[ |
533 (abs between:1 and:16r003fffff) ifTrue:[ |
488 rem := (self absFastDiv:abs) at:2. |
534 rem := (self absFastDiv:abs) at:2. |
489 |
535 ] ifFalse:[ |
490 sign < 0 ifTrue:[ |
536 rem := (self absDiv:(abs asLargeInteger)) at:2 |
491 (sign == otherSign) ifTrue:[^ rem]. |
537 ]. |
492 ^ rem sign:-1 |
538 ] ifFalse:[ |
493 ]. |
539 " |
494 (sign == otherSign) ifTrue:[^ rem]. |
540 if the argument is not a largeInteger, coerce |
495 ^ rem sign:-1 |
541 " |
496 ] |
542 (aNumber class == self class) ifFalse:[ |
497 ]. |
543 ^ self retry:#\\ coercing:aNumber |
498 |
544 ]. |
499 " |
545 |
500 if the argument is not a largeInteger, coerce |
546 rem := (self absDiv:aNumber) at:2 |
501 " |
|
502 (aNumber class == self class) ifFalse:[ |
|
503 ^ self retry:#\\ coercing:aNumber |
|
504 ]. |
547 ]. |
505 |
548 |
506 sign < 0 ifTrue:[ |
549 sign < 0 ifTrue:[ |
507 (sign == otherSign) ifTrue:[^ (self absDiv:aNumber negated) at:2]. |
550 ^ rem sign:-1 |
508 ^ ((self absDiv:aNumber) at:2) sign:-1 |
551 ]. |
509 ]. |
552 ^ rem |
510 (sign == otherSign) ifTrue:[^ (self absDiv:aNumber) at:2]. |
553 |
511 ^ ((self absDiv:aNumber negated) at:2) sign:-1 |
554 " |
512 |
555 900 \\ 400 |
513 " |
556 -900 \\ 400 |
514 9000000000 \\ 4000000000 => 1000000000 |
557 900 \\ -400 |
515 -9000000000 \\ 4000000000 => 1000000000 |
558 -900 \\ -400 |
516 9000000000 \\ -4000000000 => 1000000000 |
559 |
517 -9000000000 \\ -4000000000 => 1000000000 |
560 9000000000 \\ 4000000000 |
518 |
561 -9000000000 \\ 4000000000 |
519 9000000000 rem: 4000000000 => 1000000000 |
562 9000000000 \\ -4000000000 |
520 -9000000000 rem: 4000000000 => -1000000000 |
563 -9000000000 \\ -4000000000 |
521 9000000000 rem: -4000000000 => -1000000000 |
564 |
522 -9000000000 rem: -4000000000 => 1000000000 |
565 900 rem: 400 |
523 " |
566 -900 rem: 400 |
524 |
567 900 rem: -400 |
525 "Modified: 29.10.1996 / 20:40:33 / cg" |
568 -900 rem: -400 |
|
569 |
|
570 9000000000 rem: 4000000000 |
|
571 -9000000000 rem: 4000000000 |
|
572 9000000000 rem: -4000000000 |
|
573 -9000000000 rem: -4000000000 |
|
574 " |
|
575 |
|
576 "Modified: 5.11.1996 / 14:02:59 / cg" |
526 ! ! |
577 ! ! |
527 |
578 |
528 !LargeInteger methodsFor:'byte access'! |
579 !LargeInteger methodsFor:'byte access'! |
529 |
580 |
530 digitAt:index |
581 digitAt:index |
635 |
686 |
636 %{ /* NOCONTEXT */ |
687 %{ /* NOCONTEXT */ |
637 OBJ t; |
688 OBJ t; |
638 |
689 |
639 if (__INST(sign) == __MKSMALLINT(0)) { |
690 if (__INST(sign) == __MKSMALLINT(0)) { |
640 RETURN (__MKSMALLINT(0)); |
691 RETURN (__MKSMALLINT(0)); |
641 } |
692 } |
642 |
693 |
643 t = __INST(digitByteArray); |
694 t = __INST(digitByteArray); |
644 if (__isByteArray(t)) { |
695 if (__isByteArray(t)) { |
645 unsigned char *_digitBytes = __ByteArrayInstPtr(t)->ba_element; |
696 unsigned char *_digitBytes = __ByteArrayInstPtr(t)->ba_element; |
646 int _idx = _byteArraySize(t); |
697 int _idx = _byteArraySize(t); |
647 int _val; |
698 int _val; |
648 |
699 |
649 while ((_idx > 0) && (_digitBytes[_idx - 1] == 0)) { |
700 while ((_idx > 0) && (_digitBytes[_idx - 1] == 0)) { |
650 _idx--; |
701 _idx--; |
651 } |
702 } |
652 switch (_idx) { |
703 switch (_idx) { |
653 case 0: |
704 case 0: |
654 RETURN (__MKSMALLINT(0)); |
705 RETURN (__MKSMALLINT(0)); |
655 break; |
706 break; |
656 |
707 |
657 case 1: |
708 case 1: |
658 _val = _digitBytes[0]; |
709 _val = _digitBytes[0]; |
659 if (__INST(sign) == __MKSMALLINT(-1)) |
710 if (__INST(sign) == __MKSMALLINT(-1)) |
660 _val = -_val; |
711 _val = -_val; |
661 RETURN (__MKSMALLINT(_val)); |
712 RETURN (__MKSMALLINT(_val)); |
662 |
713 |
663 case 2: |
714 case 2: |
664 _val = (_digitBytes[1]<<8) + _digitBytes[0]; |
715 _val = (_digitBytes[1]<<8) + _digitBytes[0]; |
665 if (__INST(sign) == __MKSMALLINT(-1)) |
716 if (__INST(sign) == __MKSMALLINT(-1)) |
666 _val = -_val; |
717 _val = -_val; |
667 RETURN (__MKSMALLINT(_val)); |
718 RETURN (__MKSMALLINT(_val)); |
668 |
719 |
669 case 3: |
720 case 3: |
670 _val = (((_digitBytes[2]<<8) + _digitBytes[1])<<8) + _digitBytes[0]; |
721 _val = (((_digitBytes[2]<<8) + _digitBytes[1])<<8) + _digitBytes[0]; |
671 if (__INST(sign) == __MKSMALLINT(-1)) |
722 if (__INST(sign) == __MKSMALLINT(-1)) |
672 _val = -_val; |
723 _val = -_val; |
673 RETURN (__MKSMALLINT(_val)); |
724 RETURN (__MKSMALLINT(_val)); |
674 |
725 |
675 case 4: |
726 case 4: |
676 _val = _digitBytes[3]; |
727 _val = _digitBytes[3]; |
677 if (_val <= 0x40) { |
728 if (_val <= 0x40) { |
678 _val = (((((_val<<8) + _digitBytes[2])<<8) + _digitBytes[1])<<8) + _digitBytes[0]; |
729 _val = (((((_val<<8) + _digitBytes[2])<<8) + _digitBytes[1])<<8) + _digitBytes[0]; |
679 if (__INST(sign) == __MKSMALLINT(-1)) |
730 if (__INST(sign) == __MKSMALLINT(-1)) |
680 _val = -_val; |
731 _val = -_val; |
681 if ((_val >= _MIN_INT) && (_val <= _MAX_INT)) { |
732 if ((_val >= _MIN_INT) && (_val <= _MAX_INT)) { |
682 RETURN (__MKSMALLINT(_val)); |
733 RETURN (__MKSMALLINT(_val)); |
683 } |
734 } |
684 } |
735 } |
685 break; |
736 break; |
686 |
737 |
687 default: |
738 default: |
688 break; |
739 break; |
689 } |
740 } |
690 } |
741 } |
691 %}. |
742 %}. |
692 index := digitByteArray size. |
743 index := digitByteArray size. |
693 [(index > 0) and:[(digitByteArray at:index) == 0]] whileTrue:[ |
744 [(index > 0) and:[(digitByteArray at:index) == 0]] whileTrue:[ |
694 index := index - 1 |
745 index := index - 1 |
695 ]. |
746 ]. |
696 |
747 |
697 (index ~~ digitByteArray size) ifTrue:[ |
748 (index ~~ digitByteArray size) ifTrue:[ |
698 digitByteArray := digitByteArray copyFrom:1 to:index |
749 digitByteArray := digitByteArray copyFrom:1 to:index |
699 ]. |
750 ]. |
700 ^ self |
751 ^ self |
701 ! |
752 ! |
702 |
753 |
703 value:aSmallInteger |
754 value:aSmallInteger |
1006 rem |
1057 rem |
1007 count "{ Class: SmallInteger }" |
1058 count "{ Class: SmallInteger }" |
1008 digit "{ Class: SmallInteger }" | |
1059 digit "{ Class: SmallInteger }" | |
1009 |
1060 |
1010 anInteger == 0 ifTrue:[ |
1061 anInteger == 0 ifTrue:[ |
1011 ^ DivisionByZeroSignal raise |
1062 ^ DivisionByZeroSignal raise |
|
1063 ]. |
|
1064 |
|
1065 self = anInteger ifTrue:[ |
|
1066 ^ Array with:1 with:0 |
1012 ]. |
1067 ]. |
1013 |
1068 |
1014 tmp1 := self simpleDeepCopy. |
1069 tmp1 := self simpleDeepCopy. |
1015 tmp1 sign:1. |
1070 tmp1 sign:1. |
1016 tmp2 := anInteger simpleDeepCopy. |
1071 tmp2 := anInteger simpleDeepCopy. |
1017 tmp2 sign:1. |
1072 tmp2 sign:1. |
1018 |
1073 |
1019 (tmp1 < tmp2) ifTrue:[ |
1074 (tmp1 < tmp2) ifTrue:[ |
1020 ^ Array with:0 with:tmp1 |
1075 ^ Array with:0 with:tmp1 |
1021 ]. |
1076 ]. |
1022 |
1077 |
1023 count := 0. |
1078 count := 0. |
1024 [tmp2 < tmp1] whileTrue:[ |
1079 [tmp2 < tmp1] whileTrue:[ |
1025 tmp2 mul256. |
1080 tmp2 mul256. |
1026 count := count + 1 |
1081 count := count + 1 |
1027 ]. |
1082 ]. |
1028 |
1083 |
1029 tmp2 div256. |
1084 tmp2 div256. |
1030 |
1085 |
1031 rem := 0 asLargeInteger. |
1086 rem := 0 asLargeInteger. |
1032 rem sign:1. |
1087 rem sign:1. |
1033 |
1088 |
1034 [count == 0] whileFalse:[ |
1089 [count == 0] whileFalse:[ |
1035 digit := 0. |
1090 digit := 0. |
1036 [tmp1 >= tmp2] whileTrue:[ |
1091 [tmp1 >= tmp2] whileTrue:[ |
1037 digit := digit + 1. |
1092 digit := digit + 1. |
1038 tmp1 := tmp1 - tmp2 |
1093 tmp1 := tmp1 - tmp2 |
1039 ]. |
1094 ]. |
1040 rem := rem * 256 + digit. |
1095 rem := (rem * 256) + digit. |
1041 tmp2 div256. |
1096 tmp2 div256. |
1042 count := count - 1 |
1097 count := count - 1 |
1043 ]. |
1098 ]. |
1044 ^ Array with:rem with:tmp1 |
1099 ^ Array with:rem with:tmp1 |
|
1100 |
|
1101 "Modified: 5.11.1996 / 13:46:14 / cg" |
1045 ! |
1102 ! |
1046 |
1103 |
1047 absEq:aLargeInteger |
1104 absEq:aLargeInteger |
1048 "return true, if abs(self) = abs(theArgument)" |
1105 "return true, if abs(self) = abs(theArgument)" |
1049 |
1106 |
1402 %{ |
1461 %{ |
1403 if (__isByteArray(__INST(digitByteArray)) |
1462 if (__isByteArray(__INST(digitByteArray)) |
1404 && __isByteArray(otherDigitByteArray) |
1463 && __isByteArray(otherDigitByteArray) |
1405 && __isByteArray(resultDigitByteArray) |
1464 && __isByteArray(resultDigitByteArray) |
1406 && __bothSmallInteger(len1, len2)) { |
1465 && __bothSmallInteger(len1, len2)) { |
1407 unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element; |
1466 unsigned char *myBytes = __ByteArrayInstPtr(__INST(digitByteArray))->ba_element; |
1408 unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element; |
1467 unsigned char *otherBytes = __ByteArrayInstPtr(otherDigitByteArray)->ba_element; |
1409 unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element; |
1468 unsigned char *resultBytes = __ByteArrayInstPtr(resultDigitByteArray)->ba_element; |
1410 int _index1, _index2, _dstIndex, _idx; |
1469 int _index1, _index2, _dstIndex, _idx; |
1411 unsigned _prod, _carry, _v; |
1470 unsigned _prod, _carry, _v; |
1412 |
1471 |
1413 for (_index1 = 0; _index1 < __intVal(len1); _index1++) { |
1472 for (_index1 = 0; _index1 < __intVal(len1); _index1++) { |
1414 for (_index2 = 0; _index2 < __intVal(len2); _index2++) { |
1473 for (_index2 = 0; _index2 < __intVal(len2); _index2++) { |
1415 _dstIndex = _index1 + _index2; |
1474 _dstIndex = _index1 + _index2; |
1416 _prod = myBytes[_index1] * otherBytes[_index2]; |
1475 _prod = myBytes[_index1] * otherBytes[_index2]; |
1417 _prod += resultBytes[_dstIndex]; |
1476 _prod += resultBytes[_dstIndex]; |
1418 resultBytes[_dstIndex] = _prod & 0xFF; |
1477 resultBytes[_dstIndex] = _prod & 0xFF; |
1419 _carry = _prod >> 8; |
1478 _carry = _prod >> 8; |
1420 if (_carry) { |
1479 if (_carry) { |
1421 _idx = _dstIndex + 1; |
1480 _idx = _dstIndex + 1; |
1422 while (_carry) { |
1481 while (_carry) { |
1423 _v = resultBytes[_idx] + _carry; |
1482 _v = resultBytes[_idx] + _carry; |
1424 resultBytes[_idx] = _v & 0xFF; |
1483 resultBytes[_idx] = _v & 0xFF; |
1425 _carry = _v >> 8; |
1484 _carry = _v >> 8; |
1426 _idx = _idx + 1; |
1485 _idx = _idx + 1; |
1427 } |
1486 } |
1428 } |
1487 } |
1429 } |
1488 } |
1430 } |
1489 } |
1431 ok = true; |
1490 ok = true; |
1432 } |
1491 } |
1433 %}. |
1492 %}. |
1434 ok ifFalse:[ |
1493 ok ifFalse:[ |
1435 1 to:len1 do:[:index1 | |
1494 1 to:len1 do:[:index1 | |
1436 1 to:len2 do:[:index2 | |
1495 1 to:len2 do:[:index2 | |
1437 dstIndex := index1 + index2 - 1. |
1496 dstIndex := index1 + index2 - 1. |
1438 prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2). |
1497 prod := (digitByteArray basicAt:index1) * (otherDigitByteArray basicAt:index2). |
1439 prod := prod + (resultDigitByteArray basicAt:dstIndex). |
1498 prod := prod + (resultDigitByteArray basicAt:dstIndex). |
1440 resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF). |
1499 resultDigitByteArray basicAt:dstIndex put:(prod bitAnd:16rFF). |
1441 carry := prod bitShift:-8. |
1500 carry := prod bitShift:-8. |
1442 carry ~~ 0 ifTrue:[ |
1501 carry ~~ 0 ifTrue:[ |
1443 idx := dstIndex + 1. |
1502 idx := dstIndex + 1. |
1444 [carry ~~ 0] whileTrue:[ |
1503 [carry ~~ 0] whileTrue:[ |
1445 v := (resultDigitByteArray basicAt:idx) + carry. |
1504 v := (resultDigitByteArray basicAt:idx) + carry. |
1446 resultDigitByteArray basicAt:idx put:(v bitAnd:255). |
1505 resultDigitByteArray basicAt:idx put:(v bitAnd:255). |
1447 carry := v bitShift:-8. |
1506 carry := v bitShift:-8. |
1448 idx := idx + 1 |
1507 idx := idx + 1 |
1449 ] |
1508 ] |
1450 ] |
1509 ] |
1451 ] |
1510 ] |
1452 ]. |
1511 ]. |
1453 ]. |
1512 ]. |
1454 ^ result normalize |
1513 ^ result compressed |
1455 ! |
1514 ! |
1456 |
1515 |
1457 absPlus:aLargeInteger |
1516 absPlus:aLargeInteger |
1458 "return a LargeInteger representing abs(self) + abs(theArgument)" |
1517 "return a LargeInteger representing abs(self) + abs(theArgument)" |
1459 |
1518 |
1474 index := 1. |
1533 index := 1. |
1475 carry := 0. |
1534 carry := 0. |
1476 |
1535 |
1477 done := false. |
1536 done := false. |
1478 [done] whileFalse:[ |
1537 [done] whileFalse:[ |
1479 sum := carry. |
1538 sum := carry. |
1480 (index <= len1) ifTrue:[ |
1539 (index <= len1) ifTrue:[ |
1481 sum := sum + (digitByteArray basicAt:index). |
1540 sum := sum + (digitByteArray basicAt:index). |
1482 (index <= len2) ifTrue:[ |
1541 (index <= len2) ifTrue:[ |
1483 sum := sum + (otherDigitByteArray basicAt:index) |
1542 sum := sum + (otherDigitByteArray basicAt:index) |
1484 ] |
1543 ] |
1485 ] ifFalse:[ |
1544 ] ifFalse:[ |
1486 (index <= len2) ifTrue:[ |
1545 (index <= len2) ifTrue:[ |
1487 sum := sum + (otherDigitByteArray basicAt:index) |
1546 sum := sum + (otherDigitByteArray basicAt:index) |
1488 ] ifFalse:[ |
1547 ] ifFalse:[ |
1489 "end reached" |
1548 "end reached" |
1490 done := true |
1549 done := true |
1491 ] |
1550 ] |
1492 ]. |
1551 ]. |
1493 (sum >= 16r100) ifTrue:[ |
1552 (sum >= 16r100) ifTrue:[ |
1494 carry := 1. |
1553 carry := 1. |
1495 sum := sum - 16r100 |
1554 sum := sum - 16r100 |
1496 ] ifFalse:[ |
1555 ] ifFalse:[ |
1497 carry := 0 |
1556 carry := 0 |
1498 ]. |
1557 ]. |
1499 resultDigitByteArray basicAt:index put:sum. |
1558 resultDigitByteArray basicAt:index put:sum. |
1500 index := index + 1 |
1559 index := index + 1 |
1501 ]. |
1560 ]. |
1502 ^ result normalize |
1561 ^ result compressed |
|
1562 |
|
1563 "Modified: 5.11.1996 / 14:09:34 / cg" |
1503 ! |
1564 ! |
1504 |
1565 |
1505 div256 |
1566 div256 |
1506 "destructively divide the receiver by 256. |
1567 "destructively divide the receiver by 256. |
1507 private - used for division only" |
1568 private - used for division only" |