LargeInteger.st
changeset 18235 9f0914e019a8
parent 17648 8d017b41a3c3
child 18237 8457ae63fa44
child 18240 28af09029a8b
equal deleted inserted replaced
18234:34f00359de08 18235:9f0914e019a8
    38 "
    38 "
    39 !
    39 !
    40 
    40 
    41 documentation
    41 documentation
    42 "
    42 "
    43     This class provides arbitrary precision integers. 
    43     This class provides arbitrary precision integers.
    44     These are represented as:
    44     These are represented as:
    45       sign (-1/0/+1) and, if sign ~~ 0
    45       sign (-1/0/+1) and, if sign ~~ 0
    46       the absolute value in a ByteArray of digits with 8 bits per element;
    46       the absolute value in a ByteArray of digits with 8 bits per element;
    47       least significant 8 bits at index 1...
    47       least significant 8 bits at index 1...
    48 
    48 
    53     LargeIntegers are usually not created explicitely, but result from
    53     LargeIntegers are usually not created explicitely, but result from
    54     SmallInteger arithmetic (overflowing the SmallInteger range).
    54     SmallInteger arithmetic (overflowing the SmallInteger range).
    55     Also, results of LargeInteger operations are converted to back to
    55     Also, results of LargeInteger operations are converted to back to
    56     SmallIntegers, when possible (see #compressed).
    56     SmallIntegers, when possible (see #compressed).
    57 
    57 
    58     In contrast to ST-80, there is only one class for LargeIntegers, 
    58     In contrast to ST-80, there is only one class for LargeIntegers,
    59     which keeps the sign as an instance variable 
    59     which keeps the sign as an instance variable
    60     (ST-80 has LargePositiveInteger and LargeNegativeInteger). 
    60     (ST-80 has LargePositiveInteger and LargeNegativeInteger).
    61     Another possible change is to use 2's complement instead of sign-magnitude
    61     Another possible change is to use 2's complement instead of sign-magnitude
    62     representation, and to use the underlying CPU's native byte order (instead of LSB).
    62     representation, and to use the underlying CPU's native byte order (instead of LSB).
    63     This would allow us to use modern CPU vector/longword operations, at least for 64 and
    63     This would allow us to use modern CPU vector/longword operations, at least for 64 and
    64     128 bit numbers (which make up almost all instances in practice).
    64     128 bit numbers (which make up almost all instances in practice).
    65     As all of these are transparent to the outside world, any of it may or may not
    65     As all of these are transparent to the outside world, any of it may or may not
    66     change in the future.
    66     change in the future.
    67 
    67 
    68     [author:]
    68     [author:]
    69         Claus Gittinger
    69 	Claus Gittinger
    70 
    70 
    71     [see also:]
    71     [see also:]
    72         Number
    72 	Number
    73         Float Fraction FixedPoint
    73 	Float Fraction FixedPoint
    74         SmallInteger
    74 	SmallInteger
    75 "
    75 "
    76 !
    76 !
    77 
    77 
    78 testing
    78 testing
    79 "
    79 "
   257      from the argument, aByteArray."
   257      from the argument, aByteArray."
   258 
   258 
   259     |digits|
   259     |digits|
   260 
   260 
   261     msb == false ifTrue:[
   261     msb == false ifTrue:[
   262         digits := aByteArrayOfDigits
   262 	digits := aByteArrayOfDigits
   263     ] ifFalse:[
   263     ] ifFalse:[
   264         digits := aByteArrayOfDigits reversed
   264 	digits := aByteArrayOfDigits reversed
   265     ].
   265     ].
   266     ^ self basicNew setDigits:digits
   266     ^ self basicNew setDigits:digits
   267 
   267 
   268     "
   268     "
   269      (LargeInteger digitBytes:#[16r10 16r20 16r30 16r00] MSB:false) hexPrintString
   269      (LargeInteger digitBytes:#[16r10 16r20 16r30 16r00] MSB:false) hexPrintString
   477     "Modified: 28.7.1997 / 19:07:55 / cg"
   477     "Modified: 28.7.1997 / 19:07:55 / cg"
   478 !
   478 !
   479 
   479 
   480 // aNumber
   480 // aNumber
   481     "return the integer part of the quotient of the receivers value
   481     "return the integer part of the quotient of the receivers value
   482      and the arguments value. 
   482      and the arguments value.
   483      The result is truncated toward negative infinity
   483      The result is truncated toward negative infinity
   484      and will be negative, if the operands signs differ.
   484      and will be negative, if the operands signs differ.
   485      The following is always true:
   485      The following is always true:
   486         (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   486 	(receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   487 
   487 
   488      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   488      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   489      Especially surprising:     
   489      Especially surprising:
   490         -1 // 10 -> -1 (because -(1/10) is truncated towards next smaller integer, which is -1.
   490 	-1 // 10 -> -1 (because -(1/10) is truncated towards next smaller integer, which is -1.
   491         -10 // 3 -> -4 (because -(10/3) is truncated towards next smaller integer, which is -4.
   491 	-10 // 3 -> -4 (because -(10/3) is truncated towards next smaller integer, which is -4.
   492 
   492 
   493      See #quo: which returns -2 in the above case and #rem: which is the corresponding remainder."
   493      See #quo: which returns -2 in the above case and #rem: which is the corresponding remainder."
   494 
   494 
   495     |cls divMod quo abs "{ Class: SmallInteger }" n|
   495     |cls divMod quo abs "{ Class: SmallInteger }" n|
   496 
   496 
   500     "
   500     "
   501      this is the common case, dividing by a SmallInteger.
   501      this is the common case, dividing by a SmallInteger.
   502      Use a special method for this case ...
   502      Use a special method for this case ...
   503     "
   503     "
   504     (cls == SmallInteger) ifTrue:[
   504     (cls == SmallInteger) ifTrue:[
   505         abs := aNumber.
   505 	abs := aNumber.
   506         abs := abs abs.
   506 	abs := abs abs.
   507         (abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse:16r00ffffff)) ifTrue:[
   507 	(abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse:16r00ffffff)) ifTrue:[
   508             divMod := self absFastDivMod:abs.
   508 	    divMod := self absFastDivMod:abs.
   509         ] ifFalse:[
   509 	] ifFalse:[
   510             n := abs asLargeInteger.
   510 	    n := abs asLargeInteger.
   511         ].
   511 	].
   512     ] ifFalse:[
   512     ] ifFalse:[
   513         "
   513 	"
   514          if the argument is not a largeInteger, coerce
   514 	 if the argument is not a largeInteger, coerce
   515         "
   515 	"
   516         (cls == self class) ifFalse:[
   516 	(cls == self class) ifFalse:[
   517             ^ self retry:#// coercing:aNumber
   517 	    ^ self retry:#// coercing:aNumber
   518         ].
   518 	].
   519         n := aNumber
   519 	n := aNumber
   520     ].
   520     ].
   521 
   521 
   522     divMod isNil ifTrue:[
   522     divMod isNil ifTrue:[
   523         divMod := self absDivMod:n.
   523 	divMod := self absDivMod:n.
   524     ].
   524     ].
   525     quo := divMod at:1.
   525     quo := divMod at:1.
   526     (sign == aNumber sign) ifFalse:[
   526     (sign == aNumber sign) ifFalse:[
   527         "/ adjust for truncation if negative and there is a remainder ...
   527 	"/ adjust for truncation if negative and there is a remainder ...
   528         "/ be careful: there is one special case to care for here:
   528 	"/ be careful: there is one special case to care for here:
   529         "/ if quo is maxInt+1, the negation can be represented as a smallInt.
   529 	"/ if quo is maxInt+1, the negation can be represented as a smallInt.
   530         quo := quo sign:-1.
   530 	quo := quo sign:-1.
   531         (divMod at:2) == 0 ifFalse:[
   531 	(divMod at:2) == 0 ifFalse:[
   532             ^ quo - 1
   532 	    ^ quo - 1
   533         ].
   533 	].
   534         quo digitLength == SmallInteger maxBytes ifTrue:[
   534 	quo digitLength == SmallInteger maxBytes ifTrue:[
   535             ^ quo compressed
   535 	    ^ quo compressed
   536         ].
   536 	].
   537     ].
   537     ].
   538     ^ quo
   538     ^ quo
   539 
   539 
   540     "
   540     "
   541      (9000000000 // 4000000000)   =   (900 // 400)   ifFalse:[self halt].
   541      (9000000000 // 4000000000)   =   (900 // 400)   ifFalse:[self halt].
   564     "Modified: / 27.4.1999 / 19:50:26 / stefan"
   564     "Modified: / 27.4.1999 / 19:50:26 / stefan"
   565 !
   565 !
   566 
   566 
   567 \\ aNumber
   567 \\ aNumber
   568     "Answer the integer remainder m defined by division with truncation toward
   568     "Answer the integer remainder m defined by division with truncation toward
   569      negative infinity. 
   569      negative infinity.
   570      m < |aNumber| AND there is an integer k with (k * aNumber + m) = self
   570      m < |aNumber| AND there is an integer k with (k * aNumber + m) = self
   571 
   571 
   572      The returned remainder has the same sign as aNumber.
   572      The returned remainder has the same sign as aNumber.
   573      The following is always true:
   573      The following is always true:
   574         (receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   574 	(receiver // aNumber) * aNumber + (receiver \\ aNumber) = receiver
   575 
   575 
   576      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   576      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   577      Especially surprising:     
   577      Especially surprising:
   578         -1 \\ 10 -> 9  (because -(1/10) is truncated towards next smaller integer, which is -1,
   578 	-1 \\ 10 -> 9  (because -(1/10) is truncated towards next smaller integer, which is -1,
   579                         and -1 multiplied by 10 gives -10, so we have to add 9 to get the original -1).
   579 			and -1 multiplied by 10 gives -10, so we have to add 9 to get the original -1).
   580         -10 \\ 3 -> 2 (because -(10/3) is truncated towards next smaller integer, which is -4,
   580 	-10 \\ 3 -> 2 (because -(10/3) is truncated towards next smaller integer, which is -4,
   581                         and -4 * 4 gives -12, so we need to add 2 to get the original -10.
   581 			and -4 * 4 gives -12, so we need to add 2 to get the original -10.
   582 
   582 
   583      See #rem: which is the corresponding remainder for division via #quo:.
   583      See #rem: which is the corresponding remainder for division via #quo:.
   584 
   584 
   585      Redefined here for speed."
   585      Redefined here for speed."
   586 
   586 
   587     |abs rem negativeDivisor|
   587     |abs rem negativeDivisor|
   588 
   588 
   589     aNumber negative ifTrue:[
   589     aNumber negative ifTrue:[
   590         negativeDivisor := true.
   590 	negativeDivisor := true.
   591         abs := aNumber negated.
   591 	abs := aNumber negated.
   592     ] ifFalse:[
   592     ] ifFalse:[
   593         negativeDivisor := false.
   593 	negativeDivisor := false.
   594         abs := aNumber.
   594 	abs := aNumber.
   595     ].
   595     ].
   596 
   596 
   597     "
   597     "
   598      this is the common case, dividing by a SmallInteger.
   598      this is the common case, dividing by a SmallInteger.
   599      Use a special method for this case ...
   599      Use a special method for this case ...
   600     "
   600     "
   601     (aNumber class == SmallInteger) ifTrue:[
   601     (aNumber class == SmallInteger) ifTrue:[
   602         (abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse:16r00ffffff)) ifTrue:[
   602 	(abs between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse:16r00ffffff)) ifTrue:[
   603             rem := (self absFastDivMod:abs) at:2.
   603 	    rem := (self absFastDivMod:abs) at:2.
   604         ] ifFalse:[
   604 	] ifFalse:[
   605             rem := self absMod:abs asLargeInteger
   605 	    rem := self absMod:abs asLargeInteger
   606         ].
   606 	].
   607     ] ifFalse:[
   607     ] ifFalse:[
   608         "
   608 	"
   609          if the argument is not a largeInteger, coerce
   609 	 if the argument is not a largeInteger, coerce
   610         "
   610 	"
   611         (aNumber class == self class) ifFalse:[
   611 	(aNumber class == self class) ifFalse:[
   612             ^ self retry:#\\ coercing:aNumber
   612 	    ^ self retry:#\\ coercing:aNumber
   613         ].
   613 	].
   614 
   614 
   615         rem := self absMod:abs.
   615 	rem := self absMod:abs.
   616     ].
   616     ].
   617 
   617 
   618     rem = 0 ifFalse:[
   618     rem = 0 ifFalse:[
   619         negativeDivisor ifTrue:[
   619 	negativeDivisor ifTrue:[
   620             rem := rem sign:-1
   620 	    rem := rem sign:-1
   621         ].
   621 	].
   622         (self negative ~~ negativeDivisor) ifTrue:[
   622 	(self negative ~~ negativeDivisor) ifTrue:[
   623             "different sign, so remainder would have been negative.
   623 	    "different sign, so remainder would have been negative.
   624              rem has been rounded toward zero, this code will simulate
   624 	     rem has been rounded toward zero, this code will simulate
   625              rounding to negative infinity."
   625 	     rounding to negative infinity."
   626 
   626 
   627             rem := aNumber - rem.
   627 	    rem := aNumber - rem.
   628         ].
   628 	].
   629     ].
   629     ].
   630     ^ rem
   630     ^ rem
   631 
   631 
   632     "
   632     "
   633      (9000000000 \\ 4000000000)   = (900 \\ 400 * 10000000)  ifFalse:[self halt].
   633      (9000000000 \\ 4000000000)   = (900 \\ 400 * 10000000)  ifFalse:[self halt].
   667 
   667 
   668     "Created: / 26.10.1999 / 21:28:06 / stefan"
   668     "Created: / 26.10.1999 / 21:28:06 / stefan"
   669 !
   669 !
   670 
   670 
   671 divMod:aNumber
   671 divMod:aNumber
   672     "return an array filled with 
   672     "return an array filled with
   673         (self // aNumber) and (self \\ aNumber).
   673 	(self // aNumber) and (self \\ aNumber).
   674      The returned remainder has the same sign as aNumber.
   674      The returned remainder has the same sign as aNumber.
   675      The following is always true:
   675      The following is always true:
   676         (receiver // something) * something + (receiver \\ something) = receiver
   676 	(receiver // something) * something + (receiver \\ something) = receiver
   677 
   677 
   678      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   678      Be careful with negative results: 9 // 4 -> 2, while -9 // 4 -> -3.
   679      Especially surprising:     
   679      Especially surprising:
   680         -1 \\ 10 -> 9  (because -(1/10) is truncated towards next smaller integer, which is -1,
   680 	-1 \\ 10 -> 9  (because -(1/10) is truncated towards next smaller integer, which is -1,
   681                         and -1 multiplied by 10 gives -10, so we have to add 9 to get the original -1).
   681 			and -1 multiplied by 10 gives -10, so we have to add 9 to get the original -1).
   682         -10 \\ 3 -> 2 (because -(10/3) is truncated towards next smaller integer, which is -4,
   682 	-10 \\ 3 -> 2 (because -(10/3) is truncated towards next smaller integer, which is -4,
   683                         and -4 * 4 gives -12, so we need to add 2 to get the original -10.
   683 			and -4 * 4 gives -12, so we need to add 2 to get the original -10.
   684 
   684 
   685      This is redefined here for more performance 
   685      This is redefined here for more performance
   686      (as the remainder is generated as a side effect of division)"
   686      (as the remainder is generated as a side effect of division)"
   687 
   687 
   688     |cls n|
   688     |cls n|
   689 
   689 
   690     ((self < 0) or:[aNumber <= 0]) ifTrue:[
   690     ((self < 0) or:[aNumber <= 0]) ifTrue:[
   691         ^ super divMod:aNumber
   691 	^ super divMod:aNumber
   692     ].
   692     ].
   693 
   693 
   694     "/ only handle the common case here
   694     "/ only handle the common case here
   695     cls := aNumber class.
   695     cls := aNumber class.
   696     (cls == SmallInteger) ifTrue:[
   696     (cls == SmallInteger) ifTrue:[
   697         "
   697 	"
   698          this is the common case, dividing by a SmallInteger.
   698 	 this is the common case, dividing by a SmallInteger.
   699          Use a special method for this case ...
   699 	 Use a special method for this case ...
   700         "
   700 	"
   701         (aNumber between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse:16r00ffffff)) ifTrue:[
   701 	(aNumber between:1 and:(SmallInteger maxBytes == 8 ifTrue:16r00ffffffffff ifFalse:16r00ffffff)) ifTrue:[
   702             ^ self absFastDivMod:aNumber abs.
   702 	    ^ self absFastDivMod:aNumber abs.
   703         ].
   703 	].
   704         n := aNumber asLargeInteger.
   704 	n := aNumber asLargeInteger.
   705     ] ifFalse:[
   705     ] ifFalse:[
   706         (cls == self class) ifFalse:[
   706 	(cls == self class) ifFalse:[
   707             ^ super divMod:aNumber
   707 	    ^ super divMod:aNumber
   708         ].
   708 	].
   709         n := aNumber.
   709 	n := aNumber.
   710     ].
   710     ].
   711 
   711 
   712     ^ self absDivMod:n abs.
   712     ^ self absDivMod:n abs.
   713 
   713 
   714     "
   714     "
  1550 !
  1550 !
  1551 
  1551 
  1552 digitAt:index
  1552 digitAt:index
  1553     "return 8 bits of value, starting at byte index"
  1553     "return 8 bits of value, starting at byte index"
  1554 
  1554 
       
  1555 %{
       
  1556 #ifdef __JAVA__
       
  1557     return context._RETURN( ((STLargeInteger)self).digitAt( index.intValue() ) );
       
  1558 #endif
       
  1559 %}.
  1555     index > digitByteArray size ifTrue:[^ 0].
  1560     index > digitByteArray size ifTrue:[^ 0].
  1556     ^ digitByteArray at:index
  1561     ^ digitByteArray at:index
  1557 !
  1562 !
  1558 
  1563 
  1559 digitAt:index put:aByte
  1564 digitAt:index put:aByte
  1560     "set the 8 bits, index is a byte index"
  1565     "set the 8 bits, index is a byte index"
  1561 
  1566 
       
  1567 %{
       
  1568 #ifdef __JAVA__
       
  1569     ERROR("cannot modify the digits of a LargeInteger");
       
  1570 #endif
       
  1571 %}.
  1562     digitByteArray at:index put:aByte
  1572     digitByteArray at:index put:aByte
  1563 !
  1573 !
  1564 
  1574 
  1565 digitByteAt:index
  1575 digitByteAt:index
  1566     "return 8 bits of my signed value, starting at byte index.
  1576     "return 8 bits of my signed value, starting at byte index.
  1567      For positive receivers, this is the same as #digitAt:;
  1577      For positive receivers, this is the same as #digitAt:;
  1568      for negative ones, the actual bit representation is returned."
  1578      for negative ones, the actual bit representation is returned."
  1569 
  1579 
  1570     |t digits|
  1580     |t digits|
       
  1581 
       
  1582 %{
       
  1583 #ifdef __JAVA__
       
  1584     return context._RETURN( ((STLargeInteger)self).digitByteAt( index.intValue() ) );
       
  1585 #endif
       
  1586 %}.
  1571     sign >= 0 ifTrue:[
  1587     sign >= 0 ifTrue:[
  1572 	index > digitByteArray size ifTrue:[
  1588 	index > digitByteArray size ifTrue:[
  1573 	    ^ 0
  1589 	    ^ 0
  1574 	].
  1590 	].
  1575 	^ digitByteArray at:index.
  1591 	^ digitByteArray at:index.
  1596 digitBytes
  1612 digitBytes
  1597     "return a byteArray filled with the receivers bits
  1613     "return a byteArray filled with the receivers bits
  1598      (8 bits of the absolute value per element).
  1614      (8 bits of the absolute value per element).
  1599      Least significant byte is first!!"
  1615      Least significant byte is first!!"
  1600 
  1616 
       
  1617 %{
       
  1618 #ifdef __JAVA__
       
  1619     return context._RETURN( ((STLargeInteger)self).digitBytes() );
       
  1620 #endif
       
  1621 %}.
  1601     ^ digitByteArray
  1622     ^ digitByteArray
  1602 
  1623 
  1603     "Modified: / 5.5.1999 / 14:57:03 / stefan"
  1624     "Modified: / 5.5.1999 / 14:57:03 / stefan"
  1604 !
  1625 !
  1605 
  1626 
  1635      this allows to ask unnormalized LargeIntegers
  1656      this allows to ask unnormalized LargeIntegers
  1636      for their digitLength
  1657      for their digitLength
  1637     "
  1658     "
  1638     |l "{ Class: SmallInteger }" |
  1659     |l "{ Class: SmallInteger }" |
  1639 
  1660 
       
  1661 %{
       
  1662 #ifdef __JAVA__
       
  1663     return context._RETURN( ((STLargeInteger)self).digitLength() );
       
  1664 #endif
       
  1665 %}.
  1640     l := digitByteArray size.
  1666     l := digitByteArray size.
  1641     [l ~~ 0 and:[(digitByteArray at:l) == 0]] whileTrue:[
  1667     [l ~~ 0 and:[(digitByteArray at:l) == 0]] whileTrue:[
  1642 	l := l - 1.
  1668 	l := l - 1.
  1643     ].
  1669     ].
  1644     ^ l
  1670     ^ l
  5361 !
  5387 !
  5362 
  5388 
  5363 negative
  5389 negative
  5364     "return true, if the receiver is < 0"
  5390     "return true, if the receiver is < 0"
  5365 
  5391 
       
  5392 %{
       
  5393 #ifdef __JAVA__
       
  5394     return context._RETURN( ((STLargeInteger)self).largeValue.signum() < 0 ? STObject.True : STObject.False);
       
  5395 #endif
       
  5396 %}.
  5366     ^ (sign < 0)
  5397     ^ (sign < 0)
  5367 !
  5398 !
  5368 
  5399 
  5369 odd
  5400 odd
  5370     "return true if the receiver is odd"
  5401     "return true if the receiver is odd"
  5375 !
  5406 !
  5376 
  5407 
  5377 positive
  5408 positive
  5378     "return true, if the receiver is >= 0"
  5409     "return true, if the receiver is >= 0"
  5379 
  5410 
       
  5411 %{
       
  5412 #ifdef __JAVA__
       
  5413     return context._RETURN( ((STLargeInteger)self).largeValue.signum() >= 0 ? STObject.True : STObject.False);
       
  5414 #endif
       
  5415 %}.
  5380     ^ (sign >= 0)
  5416     ^ (sign >= 0)
  5381 !
  5417 !
  5382 
  5418 
  5383 sign
  5419 sign
  5384     "return the sign of the receiver (-1, 0 or 1)"
  5420     "return the sign of the receiver (-1, 0 or 1)"
  5385 
  5421 
       
  5422 %{
       
  5423 #ifdef __JAVA__
       
  5424     return context._RETURN( STInteger._new( ((STLargeInteger)self).largeValue.signum() ));
       
  5425 #endif
       
  5426 %}.
  5386     ^ sign
  5427     ^ sign
  5387 !
  5428 !
  5388 
  5429 
  5389 strictlyPositive
  5430 strictlyPositive
  5390     "return true, if the receiver is > 0"
  5431     "return true, if the receiver is > 0"
  5391 
  5432 
       
  5433 %{
       
  5434 #ifdef __JAVA__
       
  5435     return context._RETURN( ((STLargeInteger)self).largeValue.signum() > 0 ? STObject.True : STObject.False);
       
  5436 #endif
       
  5437 %}.
  5392     ^ (sign > 0)
  5438     ^ (sign > 0)
  5393 ! !
  5439 ! !
  5394 
  5440 
  5395 !LargeInteger class methodsFor:'documentation'!
  5441 !LargeInteger class methodsFor:'documentation'!
  5396 
  5442 
  5397 version
  5443 version
  5398     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.223 2015-03-25 14:12:51 cg Exp $'
  5444     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.224 2015-04-19 22:31:45 cg Exp $'
  5399 !
  5445 !
  5400 
  5446 
  5401 version_CVS
  5447 version_CVS
  5402     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.223 2015-03-25 14:12:51 cg Exp $'
  5448     ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.224 2015-04-19 22:31:45 cg Exp $'
  5403 ! !
  5449 ! !
  5404