12 "{ Package: 'stx:libbasic' }" |
12 "{ Package: 'stx:libbasic' }" |
13 |
13 |
14 "{ NameSpace: Smalltalk }" |
14 "{ NameSpace: Smalltalk }" |
15 |
15 |
16 Integer subclass:#LargeInteger |
16 Integer subclass:#LargeInteger |
17 instanceVariableNames:'sign digitByteArray' |
17 instanceVariableNames:'sign digitByteArray' |
18 classVariableNames:'UseKarazuba' |
18 classVariableNames:'UseKarazuba' |
19 poolDictionaries:'' |
19 poolDictionaries:'' |
20 category:'Magnitude-Numbers' |
20 category:'Magnitude-Numbers' |
21 ! |
21 ! |
22 |
22 |
23 !LargeInteger class methodsFor:'documentation'! |
23 !LargeInteger class methodsFor:'documentation'! |
24 |
24 |
25 copyright |
25 copyright |
2339 ! |
2339 ! |
2340 |
2340 |
2341 equalFromInteger:anInteger |
2341 equalFromInteger:anInteger |
2342 "sent when an integer does not know how to compare to the receiver, a largeInt" |
2342 "sent when an integer does not know how to compare to the receiver, a largeInt" |
2343 |
2343 |
|
2344 |otherClass| |
|
2345 |
2344 "/ |
2346 "/ |
2345 "/ here, we depend on the fact, that largeinteger |
2347 "/ here, we depend on the fact, that largeinteger |
2346 "/ results are always converted to smallInts, if possible. |
2348 "/ results are always converted to smallInts, if possible. |
2347 "/ therefore, a largeInt in the smallInt range is not allowed (possible) |
2349 "/ therefore, a largeInt in the smallInt range is not allowed (possible) |
2348 "/ |
2350 "/ |
2349 anInteger class == SmallInteger ifTrue:[^ false ]. |
2351 otherClass := anInteger class. |
2350 anInteger class == self class ifFalse:[ |
2352 otherClass == SmallInteger ifTrue:[^ false ]. |
2351 ^ super equalFromInteger:anInteger |
2353 otherClass == self class ifTrue:[ |
2352 ]. |
2354 (anInteger sign == sign) ifFalse:[^ false]. |
2353 (anInteger sign == sign) ifFalse:[^ false]. |
2355 ^ self absEq:anInteger |
2354 ^ self absEq:anInteger |
2356 ]. |
|
2357 ^ super equalFromInteger:anInteger |
2355 ! |
2358 ! |
2356 |
2359 |
2357 lessFromInteger:anInteger |
2360 lessFromInteger:anInteger |
2358 "sent when an integer does not know how to compare to the receiver, a largeInt. |
2361 "sent when an integer does not know how to compare to the receiver, a largeInt. |
2359 Return true if anInteger < self" |
2362 Return true if anInteger < self" |
2392 anInteger == 0 ifTrue:[^ 0]. |
2395 anInteger == 0 ifTrue:[^ 0]. |
2393 anInteger == 1 ifTrue:[^ self]. |
2396 anInteger == 1 ifTrue:[^ self]. |
2394 |
2397 |
2395 num := anInteger abs. |
2398 num := anInteger abs. |
2396 SmallInteger maxBytes == 8 ifTrue:[ |
2399 SmallInteger maxBytes == 8 ifTrue:[ |
2397 (num > 16r3FFFFFFF) ifTrue:[ |
2400 (num > 16rFFFFFFFF) ifTrue:[ |
2398 "if num is too big (so that multiplying by a byte could create a Large)" |
2401 "if num is too big (so that multiplying by a byte could create a Large)" |
2399 ^ anInteger retry:#* coercing:self |
2402 ^ anInteger retry:#* coercing:self |
2400 ]. |
2403 ]. |
2401 ] ifFalse:[ |
2404 ] ifFalse:[ |
2402 (num > 16r3FFFFF) ifTrue:[ |
2405 (num > 16r3FFFFF) ifTrue:[ |
2596 while (_l >= 4) { |
2599 while (_l >= 4) { |
2597 unsigned __t; |
2600 unsigned __t; |
2598 UINT64 _prod64; |
2601 UINT64 _prod64; |
2599 |
2602 |
2600 __t = ((unsigned *)digitP)[0]; |
2603 __t = ((unsigned *)digitP)[0]; |
2601 digitP += 4; |
|
2602 _prod64 = (INT64)_v; |
2604 _prod64 = (INT64)_v; |
2603 _prod64 *= __t; |
2605 _prod64 *= __t; |
2604 _prod64 += _carry; |
2606 _prod64 += _carry; |
2605 ((unsigned *)resultP)[0] = _prod64 /* & 0xFFFFFFFFL */; |
2607 ((unsigned *)resultP)[0] = _prod64 /* & 0xFFFFFFFFL */; |
2606 _carry = _prod64 >> 32; |
2608 _carry = _prod64 >> 32; |
|
2609 digitP += 4; |
2607 resultP += 4; |
2610 resultP += 4; |
2608 _l -= 4; |
2611 _l -= 4; |
2609 } |
2612 } |
2610 if (_l >= 2) { |
2613 if (_l >= 2) { |
2611 unsigned short __t; |
2614 unsigned short __t; |
2612 UINT64 _prod64; |
2615 UINT64 _prod64; |
2613 |
2616 |
2614 __t = ((unsigned short *)digitP)[0]; |
2617 __t = ((unsigned short *)digitP)[0]; |
2615 digitP += 2; |
|
2616 _prod64 = (INT64)_v; |
2618 _prod64 = (INT64)_v; |
2617 _prod64 *= __t; |
2619 _prod64 *= __t; |
2618 _prod64 += _carry; |
2620 _prod64 += _carry; |
2619 ((unsigned short *)resultP)[0] = _prod64 /* & 0xFFFF */; |
2621 ((unsigned short *)resultP)[0] = _prod64 /* & 0xFFFF */; |
2620 _carry = _prod64 >> 16; |
2622 _carry = _prod64 >> 16; |
|
2623 digitP += 2; |
2621 resultP += 2; |
2624 resultP += 2; |
2622 _l -= 2; |
2625 _l -= 2; |
2623 } |
2626 } |
2624 if (_l > 0) { |
2627 if (_l > 0) { |
2625 UINT64 _prod64; |
2628 UINT64 _prod64; |
4632 OBJ _uint; |
4635 OBJ _uint; |
4633 |
4636 |
4634 /* |
4637 /* |
4635 * two word-sized numbers, no carry - a very common case ... |
4638 * two word-sized numbers, no carry - a very common case ... |
4636 */ |
4639 */ |
4637 #if defined(__LSB_FIRST__) |
4640 #if defined(__LSBFIRST__) |
4638 unsigned INT _sum = *(unsigned INT *)_otherDigits + *(unsigned INT *)_myDigits; |
4641 unsigned INT _sum = *(unsigned INT *)_otherDigits + *(unsigned INT *)_myDigits; |
4639 #else |
4642 #else |
4640 unsigned INT _sum = __unsignedLongIntVal(self) + __unsignedLongIntVal(aLargeInteger); |
4643 unsigned INT _sum = __unsignedLongIntVal(self) + __unsignedLongIntVal(aLargeInteger); |
4641 #endif /* not LSB_FIRST */ |
4644 #endif /* not LSB_FIRST */ |
4642 if (_sum <= _MAX_INT) { |
4645 if (_sum <= _MAX_INT) { |
4699 /* _sum = _sum & 0xFFFFFFFF; */ |
4702 /* _sum = _sum & 0xFFFFFFFF; */ |
4700 ((unsigned long *)(&(_newDigits[_index - 1])))[0] = _sum; |
4703 ((unsigned long *)(&(_newDigits[_index - 1])))[0] = _sum; |
4701 _index += 8; |
4704 _index += 8; |
4702 } |
4705 } |
4703 } |
4706 } |
4704 # endif |
4707 # endif / notdef */ |
4705 # endif /* 64bit */ |
4708 # endif /* 64bit alpha */ |
4706 |
4709 |
4707 # if (__POINTER_SIZE__ == 8) |
4710 # if (__POINTER_SIZE__ == 8) |
4708 # if 0 /* not faster (on alpha) */ |
4711 # if 0 /* not faster */ |
4709 { |
4712 { |
4710 int _comLen7; |
4713 int _comLen7; |
4711 |
4714 |
4712 /* |
4715 /* |
4713 * have a 64bit integers; |
4716 * have a 64bit integers; |