LargeInteger.st
changeset 19157 5543dd7af087
parent 19135 e2d82660b855
child 19158 cdce727939ab
child 19162 dcefb6a62d18
equal deleted inserted replaced
19149:e144119b2852 19157:5543dd7af087
    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) {
  4666          */
  4669          */
  4667         _index = 1;
  4670         _index = 1;
  4668         _carry = 0;
  4671         _carry = 0;
  4669 
  4672 
  4670 #if defined(__LSBFIRST__)
  4673 #if defined(__LSBFIRST__)
  4671 # if (__POINTER_SIZE__ == 8) && defined(__GNUC__)
  4674 # if (__POINTER_SIZE__ == 8) && defined(__GNUC__) && defined(__alpha__) 
  4672 #  if 0  /* not faster (on alpha) */
  4675 #  if 0  /* not faster (on alpha) */
  4673         {
  4676         {
  4674             int _comLen7;
  4677             int _comLen7;
  4675 
  4678 
  4676             /*
  4679             /*
  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;