'From Cuis 2.6 of 10 August 2010 [latest update: #540] on 1 September 2010 at 2:14:22 pm'!

!Magnitude commentStamp: 'jmv 9/1/2010 12:01' prior: 0!
I'm the abstract class Magnitude that provides common protocol for objects that have
the ability to be compared along a linear dimension, such as dates or times.
Subclasses of Magnitude include Date, ArithmeticValue, and Time, as well as
Character and LookupKey.
 
 
My subclasses should implement
  < aMagnitude 
  = aMagnitude 
  hash

Here are some example of my protocol:
     3 > 4
     5 = 6
     100 max: 9
	7 between: 5 and: 10 
!


!FloatArray methodsFor: 'arithmetic' stamp: 'yo 9/14/2004 17:12'!
\\= other

	other isNumber ifTrue: [
		1 to: self size do: [:i |
			self at: i put: (self at: i) \\ other
		].
		^ self.
	].
	1 to: (self size min: other size) do: [:i |
		self at: i put: (self at: i) \\ (other at: i).
	].

! !

!FloatArray methodsFor: '*Tools-Inspector' stamp: 'ar 9/27/2005 18:33'!
inspectorClass 
	"Answer the class of the inspector to be used on the receiver.  Called by inspect; 
	use basicInspect to get a normal (less useful) type of inspector."

	^OrderedCollectionInspector! !


!Magnitude methodsFor: 'comparing' stamp: 'nice 12/31/2008 04:06'!
>= aMagnitude 
	"Answer whether the receiver is greater than or equal to the argument."

	^aMagnitude <= self! !


!Number methodsFor: 'arithmetic' stamp: 'GabrielOmarCotelli 5/23/2009 20:20'!
reciprocal
	"Returns the reciprocal of self.
	In case self is 0 the / signals ZeroDivide"
	
	^1 / self! !

!Number methodsFor: 'mathematical functions' stamp: 'GabrielOmarCotelli 5/26/2009 19:49'!
raisedToInteger: anInteger

	"The 0 raisedToInteger: 0 is an special case. In some contexts must be 1 and in others must
	be handled as an indeterminate form.
	I take the first context because that's the way that was previously handled.
	Maybe further discussion is required on this topic."
	
	|bitProbe result|

	anInteger negative ifTrue: [^(self raisedToInteger: anInteger negated) reciprocal].
	bitProbe := 1 bitShift: anInteger highBit - 1.
 	result := self class one.
  	[
		(anInteger bitAnd: bitProbe) = 0 ifFalse: [result := result * self].
       bitProbe := bitProbe bitShift: -1.
		bitProbe > 0 ]
	whileTrue: [result := result * result].
	
	^result! !

!Number methodsFor: 'truncation and round off' stamp: 'GabrielOmarCotelli 5/26/2009 21:58'!
fractionPart
	
	"Added for ANSI compatibility"
	
	^self - self integerPart! !

!Number methodsFor: 'truncation and round off' stamp: 'GabrielOmarCotelli 5/26/2009 21:57'!
integerPart
	"Added for ANSI compatibility"
	^self truncated! !

!Number methodsFor: 'truncation and round off' stamp: 'wiz 3/1/2007 20:17'!
roundDownTo: aNumber 
	"Answer the next multiple of aNumber toward negative infinity that is nearest the 
	receiver."

	^(self/aNumber) floor * aNumber! !

!Number methodsFor: 'converting' stamp: 'jmv 9/1/2010 10:43'!
asIntegerOrFloat
	"Convert to integer if integer, or to Float otherwhise."

	^self asFloat! !

!Number methodsFor: 'converting' stamp: 'nice 10/5/2009 21:28'!
asSmallPositiveDegrees
	"Return the receiver normalized to lie within the range (0, 360)"

	^self \\ 360! !

!Number methodsFor: 'printing' stamp: 'laza 3/29/2004 12:53'!
printOn: aStream
	self printOn: aStream base: 10! !

!Number methodsFor: 'printing' stamp: 'nice 9/25/2007 02:36'!
printOn: aStream base: base
	"This method should print a representation of the number for the given base,
	excluding the base prefix (and the letter r for radix)"
	
	^self subclassResponsibility! !

!Number methodsFor: 'printing' stamp: 'nice 4/24/2008 00:38'!
printShowingDecimalPlaces: placesDesired
	"Print the receiver showing precisely the given number of places desired.  If placesDesired is positive, a decimal point and that many digits after the decimal point will always be shown.  If placesDesired is zero, a whole number will be shown, without a decimal point."

	| rounder rounded frac sign integerString fractionString result |
	placesDesired <= 0 ifTrue: [^ self rounded printString].
	rounder := 10 raisedToInteger: placesDesired.
	rounded := self roundTo: rounder reciprocal.
	sign := rounded negative ifTrue: ['-'] ifFalse: [''].
	integerString := rounded abs integerPart truncated printString.
	frac := ((rounded abs fractionPart) * rounder) truncated.
	fractionString := frac printString padded: #left to: placesDesired with: $0.
	result := sign , integerString , '.' , fractionString.
	^result
"
23 printShowingDecimalPlaces: 2
23.5698 printShowingDecimalPlaces: 2
-234.567 printShowingDecimalPlaces: 5
23.4567 printShowingDecimalPlaces: 0
23.5567 printShowingDecimalPlaces: 0
-23.4567 printShowingDecimalPlaces: 0
-23.5567 printShowingDecimalPlaces: 0
100000000 printShowingDecimalPlaces: 1
0.98 printShowingDecimalPlaces: 5
-0.98 printShowingDecimalPlaces: 2
2.567 printShowingDecimalPlaces: 2
-2.567 printShowingDecimalPlaces: 2
0 printShowingDecimalPlaces: 2
"! !

!Number methodsFor: 'printing' stamp: 'laza 3/30/2004 10:50'!
printString
	^self printStringBase: 10! !

!Number methodsFor: 'printing' stamp: 'nice 9/25/2007 02:35'!
storeOn: aStream base: base
	"This method should print a representation of the number for the given base,
	including the base prefix (with letter r for radix)"
	
	^self subclassResponsibility! !

!Number methodsFor: 'comparing' stamp: 'nice 12/26/2009 18:46'!
closeTo: num
	"are these two numbers close?"

	num isFloat ifTrue: [^ num closeTo: self asFloat].
	^[self = num] ifError: [false]! !

!Number methodsFor: '*Morphic-NewCurve-testing' stamp: 'jmv 2/21/2006 13:15'!
isNonZero
	"Return true for numbers not zero and false for all other
	objects "
	^ self isZero not! !


!Float methodsFor: 'truncation and round off' stamp: 'nice 12/2/2009 17:35'!
predecessor
	| ulp |
	self isFinite ifFalse: [
		(self isNaN or: [self negative]) ifTrue: [^self].
		^Float fmax].
	self = 0.0 ifTrue: [^Float fmin negated].
	ulp := self ulp.
	^self - (0.5 * ulp) = self
		ifTrue: [self - ulp]
		ifFalse: [self - (0.5 * ulp)]! !

!Float methodsFor: 'truncation and round off' stamp: 'nice 12/2/2009 17:35'!
successor
	| ulp |
	self isFinite ifFalse: [
		(self isNaN or: [self positive]) ifTrue: [^self].
		^Float fmax negated].
	self = 0.0 ifTrue: [^Float fmin].
	ulp := self ulp.
	^self + (0.5 * ulp) = self
		ifTrue: [self + ulp]
		ifFalse: [self + (0.5 * ulp)]! !

!Float methodsFor: 'truncation and round off' stamp: 'nice 12/1/2009 12:07'!
ulp
	"Answer the unit of least precision of self (the power of two corresponding to last bit of mantissa)"
	
	| exponent |
	self isFinite ifFalse: [
		self isNaN ifTrue: [^self].
		^Float infinity].
	self = 0.0 ifTrue: [^Float fmin].
	exponent := self exponent.
	^exponent < self class emin
		ifTrue: [Float fminDenormalized]
 		ifFalse: [Float epsilon timesTwoPower: exponent]! !

!Float methodsFor: 'printing' stamp: 'nice 4/20/2010 22:48'!
absPrintExactlyOn: aStream base: base
	"Print my value on a stream in the given base.  Assumes that my value is strictly
	positive; negative numbers, zero, and NaNs have already been handled elsewhere.
	Based upon the algorithm outlined in:
	Robert G. Burger and R. Kent Dybvig
	Printing Floating Point Numbers Quickly and Accurately
	ACM SIGPLAN 1996 Conference on Programming Language Design and Implementation
	June 1996.
	This version guarantees that the printed representation exactly represents my value
	by using exact integer arithmetic."

	| significand exp baseExpEstimate r s mPlus mMinus scale roundingIncludesLimits d tc1 tc2 fixedFormat decPointCount slowbit shead |
	self isInfinite ifTrue: [aStream nextPutAll: 'Infinity'. ^ self].
	significand := self significandAsInteger.
	roundingIncludesLimits := significand even.
	exp := (self exponent - 52) max: MinValLogBase2.
	baseExpEstimate := (self exponent * base asFloat reciprocalLogBase2 - 1.0e-10) ceiling.
	exp >= 0
		ifTrue:
			[significand ~= 16r10000000000000
				ifTrue:
					[r := significand bitShift: 1 + exp.
					s := 2.
					mPlus := mMinus := 1 bitShift: exp]
				ifFalse:
					[r := significand bitShift: 2 + exp.
					s := 4.
					mPlus := 2 * (mMinus := 1 bitShift: exp)]]
		ifFalse:
			[(exp = MinValLogBase2 or: [significand ~= 16r10000000000000])
				ifTrue:
					[r := significand bitShift: 1.
					s := 1 bitShift: 1 - exp.
					mPlus := mMinus := 1]
				ifFalse:
					[r := significand bitShift: 2.
					s := 1 bitShift: 2 - exp.
					mPlus := 2.
					mMinus := 1]].
	baseExpEstimate >= 0
		ifTrue: [s := s * (base raisedToInteger: baseExpEstimate)]
		ifFalse:
			[scale := base raisedToInteger: baseExpEstimate negated.
			r := r * scale.
			mPlus := mPlus * scale.
			mMinus := mMinus * scale].
	((r + mPlus < s) not and: [roundingIncludesLimits or: [r + mPlus > s]])
		ifTrue: [baseExpEstimate := baseExpEstimate + 1]
		ifFalse:
			[r := r * base.
			mPlus := mPlus * base.
			mMinus := mMinus * base].
	(fixedFormat := baseExpEstimate between: -3 and: 6)
		ifTrue:
			[decPointCount := baseExpEstimate.
			baseExpEstimate <= 0
				ifTrue: [aStream nextPutAll: ('0.000000' truncateTo: 2 - baseExpEstimate)]]
		ifFalse:
			[decPointCount := 1].
	slowbit := 1 - s lowBit .
	shead := s bitShift: slowbit.
	[d := (r bitShift: slowbit) // shead.
	r := r - (d * s).
	(tc1 := (r > mMinus) not and: [roundingIncludesLimits or: [r < mMinus]]) |
	(tc2 := (r + mPlus < s) not and: [roundingIncludesLimits or: [r + mPlus > s]])] whileFalse:
		[aStream nextPut: (Character digitValue: d).
		r := r * base.
		mPlus := mPlus * base.
		mMinus := mMinus * base.
		decPointCount := decPointCount - 1.
		decPointCount = 0 ifTrue: [aStream nextPut: $.]].
	tc2 ifTrue:
		[(tc1 not or: [r * 2 >= s]) ifTrue: [d := d + 1]].
	aStream nextPut: (Character digitValue: d).
	decPointCount > 0
		ifTrue:
		[decPointCount - 1 to: 1 by: -1 do: [:i | aStream nextPut: $0].
		aStream nextPutAll: '.0'].
	fixedFormat ifFalse:
		[aStream nextPut: $e.
		aStream nextPutAll: (baseExpEstimate - 1) printString]! !

!Float methodsFor: 'printing' stamp: 'nice 4/20/2010 22:32'!
absPrintOn: aStream base: base
	"Print my value on a stream in the given base.  Assumes that my value is strictly
	positive; negative numbers, zero, and NaNs have already been handled elsewhere.
	Based upon the algorithm outlined in:
	Robert G. Burger and R. Kent Dybvig
	Printing Floating Point Numbers Quickly and Accurately
	ACM SIGPLAN 1996 Conference on Programming Language Design and Implementation
	June 1996.
	This version performs all calculations with Floats instead of LargeIntegers, and loses
	about 3 lsbs of accuracy compared to an exact conversion."

	| significantBits fBase exp baseExpEstimate r s mPlus mMinus scale d tc1 tc2 fixedFormat decPointCount |
	self isInfinite ifTrue: [aStream nextPutAll: 'Infinity'. ^ self].
	significantBits := 50.  "approximately 3 lsb's of accuracy loss during conversion"
	fBase := base asFloat.
	exp := self exponent.
	baseExpEstimate := (exp * fBase reciprocalLogBase2 - 1.0e-10) ceiling.
	exp >= 0
		ifTrue:
			[r := self.
			s := 1.0.
			mPlus := 1.0 timesTwoPower: exp - significantBits.
			mMinus := self significand ~= 1.0 ifTrue: [mPlus] ifFalse: [mPlus / 2.0]]
		ifFalse:
			[r := self timesTwoPower: significantBits.
			s := 1.0 timesTwoPower:  significantBits.
			mMinus := 1.0 timesTwoPower: (exp max: -1024).
			mPlus :=
				(exp = MinValLogBase2) | (self significand ~= 1.0)
					ifTrue: [mMinus]
					ifFalse: [mMinus * 2.0]].
	baseExpEstimate >= 0
		ifTrue:
			[exp = 1023
				ifTrue:   "scale down to prevent overflow to Infinity during conversion"
					[r := r / fBase.
					s := s * (fBase raisedToInteger: baseExpEstimate - 1).
					mPlus := mPlus / fBase.
					mMinus := mMinus / fBase]
				ifFalse:
					[s := s * (fBase raisedToInteger: baseExpEstimate)]]
		ifFalse:
			[exp < -1023
				ifTrue:   "scale up to prevent denorm reciprocals overflowing to Infinity"
					[d := (53 * fBase reciprocalLogBase2 - 1.0e-10) ceiling.
					scale := fBase raisedToInteger: d.
					r := r * scale.
					mPlus := mPlus * scale.
					mMinus := mMinus * scale.
					scale := fBase raisedToInteger: (baseExpEstimate + d) negated]
				ifFalse:
				[scale := fBase raisedToInteger: baseExpEstimate negated].
			s := s / scale].
	(r + mPlus >= s)
		ifTrue: [baseExpEstimate := baseExpEstimate + 1]
		ifFalse:
			[s := s / fBase].
	(fixedFormat := baseExpEstimate between: -3 and: 6)
		ifTrue:
			[decPointCount := baseExpEstimate.
			baseExpEstimate <= 0
				ifTrue: [aStream nextPutAll: ('0.000000' truncateTo: 2 - baseExpEstimate)]]
		ifFalse:
			[decPointCount := 1].
	[d := (r / s) truncated.
	r := r - (d * s).
	(tc1 := r <= mMinus) | (tc2 := r + mPlus >= s)] whileFalse:
		[aStream nextPut: (Character digitValue: d).
		r := r * fBase.
		mPlus := mPlus * fBase.
		mMinus := mMinus * fBase.
		decPointCount := decPointCount - 1.
		decPointCount = 0 ifTrue: [aStream nextPut: $.]].
	tc2 ifTrue:
		[tc1 not | (tc1 & (r*2.0 >= s)) ifTrue: [d := d + 1]].
	aStream nextPut: (Character digitValue: d).
	decPointCount > 0
		ifTrue:
		[decPointCount - 1 to: 1 by: -1 do: [:i | aStream nextPut: $0].
		aStream nextPutAll: '.0'].
	fixedFormat ifFalse:
		[aStream nextPut: $e.
		aStream nextPutAll: (baseExpEstimate - 1) printString]! !

!Float methodsFor: 'printing' stamp: 'jmv 9/1/2010 11:35'!
printPaddedWith: aCharacter to: aNumber 
	"Answer the string containing the ASCII representation of the receiver 
	padded on the left with aCharacter to be at least on aNumber 
	integerPart characters and padded the right with aCharacter to be at 
	least anInteger fractionPart characters."
	| aStream digits fPadding fLen iPadding iLen curLen periodIndex |
	aStream := WriteStream on: (String new: 10).
	self printOn: aStream.
	digits := aStream contents.
	periodIndex := digits indexOf: $..
	curLen := periodIndex - 1.
	iLen := aNumber integerPart.
	curLen < iLen
		ifTrue: [iPadding := (String new: (iLen - curLen) asInteger) atAllPut: aCharacter;
					 yourself]
		ifFalse: [iPadding := ''].
	curLen := digits size - periodIndex.
	fLen := aNumber fractionPart.
	[fLen fractionPart > 1e-6] whileTrue:
		[fLen := fLen * 10.0].
	fLen := fLen asInteger.
	curLen < fLen
		ifTrue: [fPadding := (String new: fLen - curLen) atAllPut: aCharacter;
					 yourself]
		ifFalse: [fPadding := ''].
	^ iPadding , digits , fPadding! !

!Float methodsFor: 'printing' stamp: 'nice 9/19/2009 20:17'!
printShowingDecimalPlaces: placesDesired
	"This implementation avoids any rounding error caused by rounded or roundTo:"
	
	self isFinite ifFalse: [^self printString].
	^self asTrueFraction printShowingDecimalPlaces: placesDesired! !

!Float methodsFor: 'printing' stamp: 'nice 3/15/2008 22:41'!
storeOn: aStream 
	"Print the Number exactly so it can be interpreted back unchanged"
	
	self storeOn: aStream base: 10! !

!Float methodsFor: 'printing' stamp: 'nice 10/31/2009 23:45'!
storeOn: aStream base: base 
	"Print the Number exactly so it can be interpreted back unchanged"
	self isFinite
		ifTrue: [self sign = -1 ifTrue: [aStream nextPutAll: '-'].
			base = 10 ifFalse: [aStream print: base; nextPut: $r].
			self = 0.0
				ifTrue: [aStream nextPutAll: '0.0']
				ifFalse: [self abs absPrintExactlyOn: aStream base: base]]
		ifFalse: [self isNaN
				ifTrue: [aStream nextPutAll: 'Float nan']
				ifFalse: [self > 0.0
						ifTrue: [aStream nextPutAll: 'Float infinity']
						ifFalse: [aStream nextPutAll: 'Float infinity negated']]]! !


!Fraction methodsFor: 'comparing' stamp: 'jmv 9/1/2010 13:15'!
<= aNumber
	aNumber isFraction ifTrue:
		[^ numerator * aNumber denominator <= (aNumber numerator * denominator)].
	^ aNumber adaptToFraction: self andSend: #<=! !

!Fraction methodsFor: 'comparing' stamp: 'nice 1/4/2009 20:36'!
hash
	"Hash is reimplemented because = is implemented.
	Care is taken that a Fraction equal to a Float also have an equal hash"

	| tmp |
	denominator isPowerOfTwo ifTrue: [
		"If denominator is a power of two, I can be exactly equal to a Float
		Assume the fraction is already reduced"
		tmp := self asFloat.
		tmp isFinite ifTrue: [^tmp hash]].
	^numerator hash bitXor: denominator hash! !

!Fraction methodsFor: 'printing' stamp: 'laza 3/29/2004 12:56'!
printOn: aStream base: base

	aStream nextPut: $(.
	numerator printOn: aStream base: base.
	aStream nextPut: $/.
	denominator printOn: aStream base: base.
	aStream nextPut: $).
! !

!Fraction methodsFor: 'printing' stamp: 'laza 3/29/2004 13:25'!
storeOn: aStream base: base

	aStream nextPut: $(.
	numerator storeOn: aStream base: base.
	aStream nextPut: $/.
	denominator storeOn: aStream base: base.
	aStream nextPut: $).
! !

!Fraction methodsFor: 'mathematical functions' stamp: 'nice 5/28/2010 21:01'!
ln
	"This function is defined because super ln might overflow.
	Note that < 1 is tested before converting to float in order to avoid precision loss due to gradual underflow."
	| res int |
	self < 1 ifTrue: [^self reciprocal ln negated].
	self <= 0 ifTrue: [self error: 'ln is only defined for x > 0'].
	res := super ln.
	res isFinite ifTrue: [^res].
	int := self integerPart.
	^int ln + (self / int) ln! !

!Fraction methodsFor: 'mathematical functions' stamp: 'nice 6/12/2010 00:40'!
log
	"This function is defined because super log might overflow.
	Note that < 1 is tested before converting to float in order to avoid precision loss due to gradual underflow."
	| res int |
	self < 1 ifTrue: [^self reciprocal log negated].
	self <= 0 ifTrue: [self error: 'log is only defined for x > 0'].
	res := super log.
	res isFinite ifTrue: [^res].
	int := self integerPart.
	^int log + (self / int) log! !


!Integer methodsFor: 'testing' stamp: 'dtl 1/23/2010 14:16'!
isPrime
	"Answer true if the receiver is a prime number. See isProbablyPrime for a probabilistic
	implementation that is much faster for large integers, and that is correct to an extremely
	high statistical level of confidence (effectively deterministic)."
	
	self <= 1 ifTrue: [ ^false ].
	self even ifTrue: [ ^self = 2].
	3 to: self sqrtFloor by: 2 do: [ :each |
		self \\ each = 0 ifTrue: [ ^false ] ].
	^true! !

!Integer methodsFor: 'testing' stamp: 'ul 11/25/2009 02:28'!
isProbablyPrime
	"See isProbablyPrimeWithK:andQ: for the algoritm description."
	
	| k q |
	self <= 1 ifTrue: [ ^false ].
	self even ifTrue: [ ^self = 2 ].
	k := 1.
	q := self - 1 bitShift: -1.
	[ q odd ] whileFalse: [
		q := q bitShift: -1.
		k := k + 1 ].
	25 timesRepeat: [ (self isProbablyPrimeWithK: k andQ: q) ifFalse: [ ^false ] ].
	^true! !

!Integer methodsFor: 'arithmetic' stamp: 'jmv 9/1/2010 10:16'!
// aNumber 
	| q |
	aNumber = 0 ifTrue: [^ (ZeroDivide dividend: self) signal].
	self = 0 ifTrue: [^ 0].
	q := self quo: aNumber.
	"Refer to the comment in Number>>#//."
	(q negative
		ifTrue: [q * aNumber ~= self]
		ifFalse: [q = 0 and: [self negative ~= aNumber negative]])
		ifTrue: [^ q - 1"Truncate towards minus infinity."]
		ifFalse: [^ q]! !

!Integer methodsFor: 'arithmetic' stamp: 'mga 5/11/2006 15:42'!
crossSumBase: aBase
	|aResult|
	"Precondition"
	self assert:[aBase isInteger and: [aBase >=2]].

	self < 0 ifTrue: [^self negated crossSumBase: aBase].
	self < aBase ifTrue: [^ self].
	aResult := self \\ aBase + (self // aBase crossSumBase: aBase).

	"Postcondition
	E.g. 18 crossSumBase: 10 -> 9 => 18\\(10-1) = 0"
	self assert: [((aResult \\ (aBase - 1) = 0)) = ((self \\ (aBase - 1)) =0)].
	^aResult! !

!Integer methodsFor: 'comparing' stamp: 'jmv 9/1/2010 10:19'!
<= aNumber
	aNumber isInteger ifTrue:
		[self negative == aNumber negative
			ifTrue: [self negative
						ifTrue: [^ (self digitCompare: aNumber) >= 0]
						ifFalse: [^ (self digitCompare: aNumber) <= 0]]
			ifFalse: [^ self negative]].
	^ aNumber adaptToInteger: self andSend: #<=! !

!Integer methodsFor: 'comparing' stamp: 'jmv 9/1/2010 10:19'!
>= aNumber
	aNumber isInteger ifTrue:
		[self negative == aNumber negative
			ifTrue: [self negative
						ifTrue: [^(self digitCompare: aNumber) <= 0]
						ifFalse: [^(self digitCompare: aNumber) >= 0]]
			ifFalse: [^ aNumber negative]].
	^ aNumber adaptToInteger: self andSend: #>=! !

!Integer methodsFor: 'mathematical functions' stamp: 'nice 5/28/2010 21:25'!
ln
	"This function is defined because super ln might overflow."
	| res h |
	self <= 0 ifTrue: [self error: 'ln is only defined for x > 0'].
	res := super ln.
	res isFinite ifTrue: [^res].
	h := self highBit.
	^2 ln * h + (self / (1 << h)) asFloat ln! !

!Integer methodsFor: 'mathematical functions' stamp: 'nice 6/12/2010 00:40'!
log
	"This function is defined because super log might overflow."
	| res h |
	self <= 0 ifTrue: [self error: 'log is only defined for x > 0'].
	res := super log.
	res isFinite ifTrue: [^res].
	h := self highBit.
	^2 log * h + (self / (1 << h)) asFloat log! !

!Integer methodsFor: 'mathematical functions' stamp: 'es 5/25/2005 11:04'!
raisedToInteger: exp modulo: m
	(exp = 0) ifTrue: [^ 1].
	exp even
		ifTrue: [^ (self raisedToInteger: (exp // 2) modulo: m) squared \\ m]
		ifFalse: [^ (self * (self raisedToInteger: (exp - 1) modulo: m)) \\ m].! !

!Integer methodsFor: 'mathematical functions' stamp: 'ul 11/25/2009 02:34'!
sqrtFloor
	"Return the integer part of the square root of self"

	| guess guessSquared delta |
	guess := 1 bitShift: self highBit + 1 // 2.
	[
		guessSquared := guess * guess.
		delta := guessSquared - self // (guess bitShift: 1).
		delta = 0 ] whileFalse: [
			guess := guess - delta ].
	guessSquared = self ifFalse: [ guess := guess - 1 ].
	^guess! !

!Integer methodsFor: 'bit manipulation' stamp: 'nice 3/21/2008 21:47'!
bitAt: anInteger
	"Answer 1 if the bit at position anInteger is set to 1, 0 otherwise.
	self is considered an infinite sequence of bits, so anInteger can be any strictly positive integer.
	Bit at position 1 is the least significant bit.
	Negative numbers are in two-complements.
	
	This is a naive implementation that can be refined in subclass for speed"
	
	^(self bitShift: 1 - anInteger) bitAnd: 1! !

!Integer methodsFor: 'bit manipulation' stamp: 'nice 2/16/2010 10:07'!
bitAt: anInteger put: value
	"Answer a new Integer that has the bit of rank anInteger set to value.
	The bit value should be 0 or 1, otherwise raise an Error.
	The bits are indexed starting at 1 for the least significant bit.
	For negative integers, operate on 2-complement representation."
	
	| b |
	b := self bitAt: anInteger.
	b = value ifTrue: [^self].
	0 = value ifTrue: [^self bitAnd: (1 bitShift: anInteger - 1) bitInvert].
	1 = value ifTrue: [^self bitOr: (1 bitShift: anInteger - 1)].
	self error: 'bit value should be 0 or 1'! !

!Integer methodsFor: 'converting' stamp: 'MarcusDenker 12/2/2009 12:54'!
asFraction
	"Answer a Fraction that represents the value of the receiver."

	^Fraction numerator: self denominator: 1! !

!Integer methodsFor: 'converting' stamp: 'jmv 9/1/2010 10:43'!
asIntegerOrFloat
	"Convert to integer if integer, or to Float otherwhise."

	^self! !

!Integer methodsFor: 'printing' stamp: 'eem 5/21/2010 11:06'!
hex
	"Print the receiver as hex, prefixed with 16r.  DO NOT CHANGE THIS!!  The Cog VMMaker depends on this.
	 Consider using any of
		printStringHex
		printStringBase: 16
		printStringBase: 16 length: 8 padded: true
		storeStringHex
		storeStringBase: 16
		storeStringBase: 16 length: 11 padded: true"
	^self storeStringBase: 16! !

!Integer methodsFor: 'printing' stamp: 'nice 2/15/2008 21:49'!
printOn: aStream
	^self printOn: aStream base: 10! !

!Integer methodsFor: 'printing' stamp: 'jmv 9/1/2010 11:35'!
printOn: outputStream base: baseInteger showRadix: flagBoolean 
	"Write a sequence of characters that describes the receiver in radix 
	baseInteger with optional radix specifier. 
	The result is undefined if baseInteger less than 2 or greater than 36."
	| tempString startPos |

	tempString := self printStringRadix: baseInteger.
	flagBoolean ifTrue: [^ outputStream nextPutAll: tempString].
	startPos := (tempString indexOf: $r ifAbsent: [self error: 'radix indicator not found.'])
				+ 1.
	self negative ifTrue: [outputStream nextPut: $-].
	outputStream nextPutAll: (tempString copyFrom: startPos to: tempString size)! !

!Integer methodsFor: 'printing' stamp: 'jmv 9/1/2010 11:37'!
printPaddedWith: aCharacter to: anInteger 
	"Answer the string containing the ASCII representation of the receiver 
	padded on the left with aCharacter to be at least anInteger characters."
	^ self
		printPaddedWith: aCharacter
		to: anInteger
		base: 10! !

!Integer methodsFor: 'printing' stamp: 'jmv 9/1/2010 11:37'!
printPaddedWith: aCharacter to: anInteger base: aRadix 
	"Answer the string containing the ASCII representation of the receiver 
	padded on the left with aCharacter to be at least anInteger characters."
	| aStream padding digits |
	aStream := WriteStream on: (String new: 10).
	self
		printOn: aStream
		base: aRadix
		showRadix: false.
	digits := aStream contents.
	padding := anInteger - digits size.
	padding > 0 ifFalse: [^ digits].
	^ ((String new: padding) atAllPut: aCharacter;
	 yourself) , digits! !

!Integer methodsFor: 'printing' stamp: 'nice 2/15/2008 21:49'!
printString
	"For Integer, prefer the stream version to the string version for efficiency"
	
	^String streamContents: [:str | self printOn: str base: 10]! !

!Integer methodsFor: 'printing' stamp: 'jmv 9/1/2010 11:35'!
printStringRadix: baseInteger 
	"Return a string containing a sequence of characters that represents the 
	numeric value of the receiver in the radix specified by the argument.  
	If the receiver is negative, a minus sign ('-') is prepended to the 
	sequence of characters. 
	The result is undefined if baseInteger less than 2 or greater than 36."
	| tempString |
	baseInteger = 10
		ifTrue: 
			[tempString := self storeStringBase: baseInteger.
			self negative
				ifTrue: [^ '-10r' , (tempString copyFrom: 2 to: tempString size)]
				ifFalse: [^ '10r' , tempString]].
	^ self storeStringBase: baseInteger! !

!Integer methodsFor: 'private' stamp: 'es 5/31/2005 09:30'!
isProbablyPrimeWithK: k andQ: q 
	"Algorithm P, probabilistic primality test, from
	Knuth, Donald E. 'The Art of Computer Programming', Vol 2,
	Third Edition, section 4.5.4, page 395, P1-P5 refer to Knuth description."

	"P1"

	| x j y |
	x := (self - 2) atRandom + 1.
	"P2"
	j := 0.
	y := x raisedToInteger: q modulo: self.
	"P3"
	
	[(((j = 0) & (y = 1)) | (y = (self - 1))) ifTrue: [^true].
	((j > 0) & (y = 1)) ifTrue: [^false].	"P5"
	true]  
			whileTrue: 
				[j := j + 1.
				(j < k) ifTrue: [y := y squared \\ self]
				ifFalse:[^ false]]! !

!Integer methodsFor: 'private' stamp: 'laza 3/29/2004 18:16'!
print: positiveNumberString on: aStream prefix: prefix length: minimum padded: zeroFlag
	| padLength |
	padLength := minimum - positiveNumberString size - prefix size.
	padLength > 0
		ifTrue: [zeroFlag
				ifTrue: [aStream nextPutAll: prefix; nextPutAll: (String new: padLength withAll: $0)]
				ifFalse: [aStream nextPutAll: (String new: padLength withAll: Character space); nextPutAll: prefix]]
		ifFalse: [aStream nextPutAll: prefix].
	aStream nextPutAll: positiveNumberString
	! !

!Integer methodsFor: '*Morphic-Explorer' stamp: 'ul 11/11/2009 19:47'!
explorerContents

	^#(
		('hexadecimal' 16)
		('octal' 8)
		('binary' 2)) collect: [ :each |
			ObjectExplorerWrapper
				with: each first translated
				name: (self printStringBase: each second)
				model: self ]! !

!Integer methodsFor: '*Morphic-Explorer' stamp: 'laza 3/17/2005 13:38'!
hasContentsInExplorer
	^true! !

!Integer methodsFor: '*files' stamp: 'jmv 9/1/2010 10:47'!
asBytesDescription
	"Answer a terse, easily-readable representation of this Integer reprsenting a number of bytes.  Useful for file-browsers.
	123 asBytesDescription
	(12*1024) asBytesDescription
	1024 asBytesDescription
	(1024*1024) asBytesDescription
	(1024*1024*1024) asBytesDescription
	(1024*1024*1024*1024) asBytesDescription
	(30 factorial) asBytesDescription
	"
	| suffixes |
	suffixes := { 'K'"ilobytes". 'M'"egabytes". 'G'"igabytes". 'T'"erabytes". 'P'"etabytes". 'E'"xabytes". 'Z'"ettabytes". 'Y'"ottabytes"}.
	suffixes size to: 1 by: -1 do:
		[ : index |  | units |
		units := 1024 raisedTo: index.
		self >= units ifTrue: [ ^ ((self / units) roundTo: 1/100) asIntegerOrFloat asString, (suffixes at: index) ] ].
	^ self asString! !

!Integer methodsFor: 'printing-numerative' stamp: 'nice 2/15/2008 21:52'!
printOn: aStream base: base
	^self subclassResponsibility! !

!Integer methodsFor: 'printing-numerative' stamp: 'laza 3/29/2004 18:13'!
printOn: aStream base: base length: minimum padded: zeroFlag
	| prefix |
	prefix := self negative ifTrue: ['-'] ifFalse: [String new].
	self print: (self abs printStringBase: base) on: aStream prefix: prefix length: minimum padded: zeroFlag
! !

!Integer methodsFor: 'printing-numerative' stamp: 'nice 2/15/2008 21:44'!
printOn: aStream base: b nDigits: n 
	"Append a representation of this number in base b on aStream using nDigits.
	self must be positive."

	self subclassResponsibility! !

!Integer methodsFor: 'printing-numerative' stamp: 'laza 3/29/2004 18:14'!
printStringBase: base length: minimum padded: zeroFlag
	^String streamContents: [:s| self printOn: s base: base length: minimum padded: zeroFlag]! !

!Integer methodsFor: 'printing-numerative' stamp: 'laza 3/29/2004 10:58'!
printStringHex
	^self printStringBase: 16! !

!Integer methodsFor: 'printing-numerative' stamp: 'laza 3/29/2004 18:21'!
printStringLength: minimal
	^self printStringLength: minimal padded: false
! !

!Integer methodsFor: 'printing-numerative' stamp: 'laza 3/29/2004 18:20'!
printStringLength: minimal padded: zeroFlag
	^self printStringBase: 10 length: minimal padded: zeroFlag! !

!Integer methodsFor: 'printing-numerative' stamp: 'laza 3/29/2004 18:20'!
printStringPadded: minimal
	^self printStringLength: minimal padded: true
! !

!Integer methodsFor: 'printing-numerative' stamp: 'nice 12/13/2009 17:59'!
printStringRoman
	^String streamContents: [:stream | | integer |
		integer := self negative ifTrue: [stream nextPut: $-. self negated] ifFalse: [self].
		integer // 1000 timesRepeat: [stream nextPut: $M].
		integer
			romanDigits: 'MDC' for: 100 on: stream;
			romanDigits: 'CLX' for: 10 on: stream;
			romanDigits: 'XVI' for: 1 on: stream]! !

!Integer methodsFor: 'printing-numerative' stamp: 'laza 3/29/2004 13:36'!
storeOn: aStream base: base
	"Print a representation of the receiver on the stream
	<aStream> in base <base> where
	2 <= <baseInteger> <= 16. If <base> is other than 10
	it is written first separated by $r followed by the number
	like for example: 16rFCE2"

	| integer |
	integer := self negative
		ifTrue: [aStream nextPut: $-. self negated]
		ifFalse: [self].
	base = 10 ifFalse: [aStream nextPutAll: base printString; nextPut: $r].
	aStream nextPutAll: (integer printStringBase: base).
! !

!Integer methodsFor: 'printing-numerative' stamp: 'laza 3/29/2004 18:16'!
storeOn: aStream base: base length: minimum padded: zeroFlag
	| prefix |
	prefix := self negative ifTrue: ['-'] ifFalse: [String new].
	base = 10 ifFalse: [prefix := prefix, base printString, 'r'].
	self print: (self abs printStringBase: base) on: aStream prefix: prefix length: minimum padded: zeroFlag
! !

!Integer methodsFor: 'printing-numerative' stamp: 'laza 3/29/2004 18:16'!
storeStringBase: base length: minimum padded: zeroFlag
	^String streamContents: [:s| self storeOn: s base: base length: minimum padded: zeroFlag]! !

!Integer methodsFor: 'printing-numerative' stamp: 'laza 3/29/2004 10:58'!
storeStringHex
	^self storeStringBase: 16! !


!LargePositiveInteger methodsFor: 'bit manipulation' stamp: 'nice 3/21/2008 00:09'!
bitAt: anInteger
	"Optimize super algorithm to avoid long bit operations.
	Instead work on digits which are known to be SmallInteger and fast.
	Note that this algorithm does not work for negative integers."
	
	| digitIndex bitIndex |
	digitIndex := anInteger - 1 // 8 + 1.
	digitIndex > self digitLength ifTrue: [^0].
	bitIndex := anInteger - 1 \\ 8 + 1.
	^(self digitAt: digitIndex) bitAt: bitIndex! !

!LargePositiveInteger methodsFor: 'testing' stamp: 'nice 8/31/2008 00:07'!
isLarge
	^true! !

!LargePositiveInteger methodsFor: 'testing' stamp: 'dtl 1/23/2010 14:30'!
isPrime
	"Answer true if the receiver is a prime number. Use a probabilistic implementation	 that
	is much faster for large integers, and that is correct to an extremely high statistical
	level of confidence (effectively deterministic)."

	^ self isProbablyPrime! !

!LargePositiveInteger methodsFor: 'printing' stamp: 'nice 7/22/2008 00:13'!
printOn: aStream base: b
	"Append a representation of this number in base b on aStream.
	In order to reduce cost of LargePositiveInteger ops, split the number in approximately two equal parts in number of digits."
	
	| halfDigits halfPower head tail nDigitsUnderestimate |
	"Don't engage any arithmetic if not normalized"
	(self digitLength = 0 or: [(self digitAt: self digitLength) = 0]) ifTrue: [^self normalize printOn: aStream base: b].
	
	nDigitsUnderestimate := b = 10
		ifTrue: [((self highBit - 1) * 3 quo: 10) + 1 "because 1024 is almost a kilo"]
		ifFalse: [self highBit quo: b highBit].
		
	"splitting digits with a whole power of two is more efficient"
	halfDigits := 1 bitShift: nDigitsUnderestimate highBit - 2.
	
	halfDigits <= 1
		ifTrue: ["Hmmm, this could happen only in case of a huge base b... Let lower level fail"
			^self printOn: aStream base: b nDigits: (self numberOfDigitsInBase: b)].
	
	"Separate in two halves, head and tail"
	halfPower := b raisedToInteger: halfDigits.
	head := self quo: halfPower.
	tail := self - (head * halfPower).
	
	"print head"
	head printOn: aStream base: b.
	
	"print tail without the overhead to count the digits"
	tail printOn: aStream base: b nDigits: halfDigits! !

!LargePositiveInteger methodsFor: 'printing' stamp: 'ul 8/23/2010 13:56'!
printOn: aStream base: b nDigits: n
	"Append a representation of this number in base b on aStream using n digits.
	In order to reduce cost of LargePositiveInteger ops, split the number of digts approximatily in two
	Should be invoked with: 0 <= self < (b raisedToInteger: n)"
	
	| halfPower half head tail |
	n <= 1 ifTrue: [
		n <= 0 ifTrue: [self error: 'Number of digits n should be > 0'].
		
		"Note: this is to stop an infinite loop if one ever attempts to print with a huge base
		This can happen because choice was to not hardcode any limit for base b
		We let Character>>#digitValue: fail"
		^aStream nextPut: (Character digitValue: self) ].
	halfPower := n bitShift: -1.
	half := b raisedToInteger: halfPower.
	head := self quo: half.
	tail := self - (head * half).
	head printOn: aStream base: b nDigits: n - halfPower.
	tail printOn: aStream base: b nDigits: halfPower! !

!LargePositiveInteger methodsFor: 'printing' stamp: 'nice 7/6/2008 00:34'!
printStringBase: base
	"For LargeIntegers, it's faster to use the stream version.
	This reproduces Number implementation to avoid speed down if one defines Integer>>#printStringBase:
	This method should be removed if  Integer>>#printStringBase: is removed.
	Note: tests preallocating stream space with exact numberOfDigitsInBase: did not gain speed"
	
	^String streamContents: [:str | self printOn: str base: base]! !


!LargeNegativeInteger methodsFor: 'bit manipulation' stamp: 'nice 3/21/2008 01:02'!
bitAt: anInteger
	"super would not work because we have to pretend we are in two-complement.
	this has to be tricky..."
	
	| digitIndex bitIndex i |
	digitIndex := anInteger - 1 // 8 + 1.
	digitIndex > self digitLength ifTrue: [^1].
	bitIndex := anInteger - 1 \\ 8 + 1.

	i := 1.
	[i = digitIndex
		ifTrue:
			["evaluate two complement (bitInvert + 1) on the digit :
			(if digitIndex > 1, we must still add 1 due to the carry).
			but x bitInvert is -1-x, bitInvert+1 is just x negated..."
			^(self digitAt: digitIndex) negated bitAt: bitIndex].
	(self digitAt: i) = 0]
		whileTrue: [
			"two complement (bitInvert + 1) raises a carry:
			0 bitInvert -> 2r11111111.  2r11111111 + 1 -> 0 with carry...
			Thus we must inquire one digit forward"
			i := i + 1].
	
	"We escaped the while loop, because there is no more carry.
	Do a simple bitInvert without a carry"
	^1 - ((self digitAt: digitIndex) bitAt: bitIndex)! !

!LargeNegativeInteger methodsFor: 'printing' stamp: 'nice 2/15/2008 21:47'!
printOn: aStream base: b
	"Append a representation of this number in base b on aStream."
	
	aStream nextPut: $-.
	self abs printOn: aStream base: b! !


!Number class methodsFor: 'instance creation' stamp: 'jmv 9/1/2010 14:10'!
readRemainderOf: integerPart from: aStream base: base withSign: sign
	"Read optional fractional part and exponent, and return the final result"
	| value fraction fracpos peekChar |

	value := integerPart.
	(aStream peekFor: $.)
		ifTrue: [		 "<integer>.<fraction>"
			(aStream atEnd not and: [ aStream peek digitValue between: 0 and: base - 1 ])
				ifTrue:  [
					fracpos := aStream position.
					fraction := Integer readFrom: aStream base: base.
					fraction := fraction asFloat / (base raisedTo: aStream position - fracpos).
					value := value asFloat + fraction]
				ifFalse: [
					"oops - just <integer>."
					aStream skip: -1.
					"un-gobble the period"
					^ value * sign"Number readFrom: '3r-22.2'"]].
	peekChar := aStream peek.
	peekChar = $e | (peekChar = $d) | (peekChar = $q)
		ifTrue: [			"<number>(e|d|q)<exponent>>"
			aStream next.
			(aStream atEnd not and: [ (aStream peek digitValue between: 0 and: 9) or: [ aStream peek = $- ]])
				ifTrue:  [
					value := value * (base raisedTo: (Integer readFrom: aStream)) ]
				ifFalse: [
					"oops - just <number>."
					aStream skip: -1.]].
	^(value isFloat
		and: [ value = 0.0 and: [ sign = -1 ]])
			ifTrue: [ Float negativeZero ]
			ifFalse: [ value * sign ]! !


!Float class methodsFor: 'constants' stamp: 'nice 6/11/2009 12:29'!
denormalized
	"Answer whether implementation supports denormalized numbers (also known as gradual underflow)."
	
	^true! !

!Float class methodsFor: 'constants' stamp: 'nice 6/8/2009 15:42'!
emax
	"Answer exponent of maximal representable value"
	
	^1023! !

!Float class methodsFor: 'constants' stamp: 'nice 6/8/2009 15:43'!
emin
	"Answer exponent of minimal normalized representable value"
	
	^-1022! !

!Float class methodsFor: 'constants' stamp: 'nice 6/11/2009 12:30'!
epsilon
	"Answer difference between 1.0 and previous representable value"
	
	^1.0 timesTwoPower: 1 - self precision! !

!Float class methodsFor: 'constants' stamp: 'nice 6/8/2009 15:20'!
fmax
	"Answer the maximum finite floating point value representable."
	
	^MaxVal! !

!Float class methodsFor: 'constants' stamp: 'nice 6/8/2009 15:33'!
fmin
	"Answer minimum positive representable value."
	
	^self denormalized
		ifTrue: [self fminDenormalized]
		ifFalse: [self fminNormalized]! !

!Float class methodsFor: 'constants' stamp: 'nice 6/8/2009 15:22'!
fminDenormalized
	"Answer the minimum denormalized value representable."
	
	^1.0 timesTwoPower: MinValLogBase2! !

!Float class methodsFor: 'constants' stamp: 'nice 6/8/2009 15:22'!
fminNormalized
	"Answer the minimum normalized value representable."
	
	^1.0 timesTwoPower: -1022! !

!Float class methodsFor: 'constants' stamp: 'nice 6/11/2009 12:40'!
precision
	"Answer the apparent precision of the floating point representation.
	That is the maximum number of radix-based digits (bits if radix=2) representable in floating point without round off error.
	Technically, 52 bits are stored in the representation, and normalized numbers have an implied leading 1 that does not need to be stored.
	Note that denormalized floating point numbers don't have the implied leading 1, and thus gradually loose precision.
	This format conforms IEEE 754 double precision standard."
	
	^53! !

!Float class methodsFor: 'constants' stamp: 'nice 6/8/2009 15:16'!
radix
	"Answer the radix used for internal floating point representation."
	
	^2! !

!Float class methodsFor: 'constants' stamp: 'yo 6/17/2004 17:41'!
twoPi

	^ Twopi
! !


!Integer class methodsFor: 'prime numbers' stamp: 'md 2/13/2006 14:38'!
primesUpTo: max do: aBlock
	"Compute aBlock with all prime integers up to the given integer."
	"Integer primesUpTo: 100"

	| limit flags prime k |
	limit := max asInteger - 1.
	"Fall back into #largePrimesUpTo:do: if we'd require more than 100k of memory; 
	the alternative will only requre 1/154th of the amount we need here and is almost as fast."
	limit > 25000 ifTrue:[^self largePrimesUpTo: max do: aBlock].
	flags := (Array new: limit) atAllPut: true.
	1 to: limit - 1 do: [:i |
		(flags at: i) ifTrue: [
			prime := i + 1.
			k := i + prime.
			[k <= limit] whileTrue: [
				flags at: k put: false.
				k := k + prime].
			aBlock value: prime]].
! !

!Integer class methodsFor: 'prime numbers' stamp: 'nice 12/27/2009 03:11'!
verbosePrimesUpTo: max do: aBlock
	"Integer verbosePrimesUpTo: SmallInteger maxVal" "<- heh, heh"
	"Compute primes up to max, but be verbose about it"
	| lastTime |
	lastTime := Time millisecondClockValue.
	Utilities informUserDuring:[:bar|
		bar value:'Computing primes...'.
		self primesUpTo: max do:[:prime| | nowTime |
			aBlock value: prime.
			nowTime := Time millisecondClockValue.
			(nowTime - lastTime > 1000) ifTrue:[
				lastTime := nowTime.
				bar value:'Last prime found: ', prime printString]]].! !

!Integer class methodsFor: 'compatibility' stamp: 'laza 10/16/2004 14:34'!
readFrom: aStream radix: radix
	^self readFrom: aStream base: radix! !


!SmallInteger methodsFor: 'bit manipulation' stamp: 'nice 11/27/2009 19:49'!
lowBit
	" Answer the index of the low order one bit.
		2r00101000 lowBit       (Answers: 4)
		2r-00101000 lowBit      (Answers: 4)
	  First we skip bits in groups of 8, then do a lookup in a table.
	  While not optimal, this is a good tradeoff; long
	  integer #lowBit always invokes us with bytes."
	| n result lastByte |
	n := self.
	n = 0 ifTrue: [ ^ 0 ].
	result := 0.
	[(lastByte := n bitAnd: 16rFF) = 0]
		whileTrue: [
			result := result + 8.
			n := n bitShift: -8 ].

	"The low bits table can be obtained with:
	((1 to: 8) inject: #[1] into: [:lowBits :rank | (lowBits copy at: 1 put: lowBits first + 1; yourself) , lowBits]) allButFirst."
	^result + ( #[1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 6 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 7 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 6 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 8 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 6 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 7 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 6 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1] at: lastByte)! !

!SmallInteger methodsFor: 'testing' stamp: 'nice 8/31/2008 00:07'!
isLarge
	^false! !

!SmallInteger methodsFor: 'printing' stamp: 'nice 2/15/2008 21:43'!
printOn: aStream base: b 
	"Append a representation of this number in base b on aStream."

	self < 0
		ifTrue: [aStream nextPut: $-.
			aStream nextPutAll: (self negated printStringBase: b).
			^self].

	"allocating a String seems faster than streaming for SmallInteger"
	aStream nextPutAll: (self printStringBase: b)! !

!SmallInteger methodsFor: 'printing' stamp: 'nice 2/15/2008 21:42'!
printOn: aStream base: b nDigits: n 
	"Append a representation of this number in base b on aStream using nDigits.
	self must be positive."

	"allocating a String seems faster than streaming for SmallInteger"
	aStream nextPutAll: (self printStringBase: b nDigits: n)! !

!SmallInteger methodsFor: 'printing' stamp: 'gk 5/25/2007 15:08'!
printString
	"Highly optimized version for base 10
	and that we know it is a SmallInteger."
	
	| integer next result len |
	self = 0 ifTrue: [^'0'].
	self < 0 ifTrue: [^'-', self negated printString].
	len := self decimalDigitLength.
	result := String new: len.
	integer := self.
	len to: 1 by: -1 do: [:i |
		next := integer // 10.
		result byteAt: i put: 48 + (integer - (next * 10)).
		integer := next].
	^result! !

!SmallInteger methodsFor: 'printing' stamp: 'nice 7/6/2008 00:48'!
printStringBase: b 
	"Return a String representation of this number in base b.
	For SmallIntegers, it is more efficient to print directly in a String,
	rather than using a Stream like super."

	self < 0
		ifTrue: [^ '-'
				, (self negated printStringBase: b)].
	self < b
		ifTrue: [^ String
				with: (Character digitValue: self)].
	^ self printStringBase: b nDigits: (self numberOfDigitsInBase: b)! !

!SmallInteger methodsFor: 'printing' stamp: 'nice 2/15/2008 21:39'!
printStringBase: b nDigits: n
	"Return a string representation of this number in base b with n digits (left padded with 0).
	Should be invoked with: 0 <= self < (b raisedToInteger: n)."
	
	| integer next result |
	result := String new: n.
	integer := self.
	n to: 1 by: -1 do: [:i |
		next := integer // b.
		result byteAt: i put: (Character digitValue: (integer - (next * b))).
		integer := next].
	^result! !

!SmallInteger methodsFor: 'private' stamp: 'nice 11/27/2009 19:58'!
highBitOfPositiveReceiver
	| shifted bitNo |
	"Answer the index of the high order bit of the receiver, or zero if the 
	receiver is zero. Receiver has to be positive!!"
	shifted := self.
	bitNo := 0.
	[shifted < 65536]
		whileFalse: 
			[shifted := shifted bitShift: -16.
			bitNo := bitNo + 16].
	shifted < 256
		ifFalse: 
			[shifted := shifted bitShift: -8.
			bitNo := bitNo + 8].
		
	"The high bits table can be obtained with:
	(1 to: 8) inject: #[0] into: [:highBits :rank | highBits , (highBits collect: [:e | rank])]."
	^bitNo + ( #[0 1 2 2 3 3 3 3 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8] at: shifted + 1)! !

Float class removeSelector: #readFrom:ifFail:!
