!=========================================================================
! Copyright (C) VMware, Inc. 1986-2011.  All Rights Reserved.
!
! $Id: integer.gs,v 1.15 2008-01-09 22:50:12 stever Exp $
!
! Superclass Hierarchy:
!   Integer, Number, Magnitude, Object.
!
!=========================================================================

! fix 34008
removeallmethods Integer
removeallclassmethods Integer

category: 'For Documentation Installation only'
classmethod: Integer
installDocumentation

| doc txt |
doc := GsClassDocumentation newForClass: self.

txt := (GsDocText new) details:
'This is an abstract superclass that establishes protocol for all GemStone
 Smalltalk integers.  Concrete subclasses include LargePositiveInteger,
 LargeNegativeInteger, and SmallInteger.'.
doc documentClassWith: txt.

txt := (GsDocText new) details:
'For purposes of bit manipulation, Integers are treated as two''s-complement,
infinite-precision binary numbers.'.
doc documentCategory: #'Bit Manipulation' with: txt.

self description: doc.
%

category: 'Instance Creation'
classmethod: Integer
fromCompleteString: aString

"Returns an instance of the appropriate subclass, reconstructed from aString.
 Leading blanks and trailing blanks are permitted.  Trailing non-digits
 generate an error.

 Smalltalk radix syntax for non-base-10 numbers is supported."

<primitive: 343>

" non-primitive implementation handles error conditions and arguments that
  are not a kind of String "
| s result |

s := ReadStream on: aString.
result := self fromStream: s.
[ s atEnd ]
whileFalse:
  [ (s next isEquivalent:  $ )
    ifFalse:
      [ ^ self _errIncorrectFormat: aString ]
  ].
^ result

%

category: 'Instance Creation'
classmethod: Integer
fromString: aString

"Returns an instance of the appropriate subclass, reconstructed from aString.
 Leading blanks and trailing blanks are permitted.  Trailing non-digits
 terminate the conversion without raising any errors.

 Smalltalk radix syntax for non-base-10 numbers is supported."

<primitive: 267>

" non-primitive implementation handles error conditions and arguments that
  are not a kind of String "
| s result |

s := ReadStream on: aString.
result := self fromStream: s.
^ result
%

category: 'Instance Creation'
classmethod: Integer
_new: length neg: neg

"Returns an instance of a large integer whose size is length.  The argument neg
 is a flag that determines whether or not the integer is negative."

<primitive: 266>

^self _error: #rtErrArgOutOfRange
%

category: 'Private'
classmethod: Integer
_newWithValue: aSmallInt

"Provided for use in testing the image .  
 Returns a subnormal large integer equal to the argument.

 The absolute value of aSmallInt must be a SmallInteger . "

| res arg isNeg idx |
isNeg := aSmallInt < 0 .
arg := aSmallInt .
isNeg ifTrue:[ arg := arg negated ].
arg _validateClass: SmallInteger.
res := self _new: 5 neg: isNeg .
idx := 1 .
[arg == 0] whileFalse:[ | aDig |
  aDig := arg bitAnd: 16r7fff . 
  res _digitAt: idx put: aDig .
  idx := idx + 1 .
  arg := arg bitShift: -15 .
].
^ res
%


category: 'Constants'
classmethod: Integer
_selectedPrimeGreaterThan: anInteger

"Returns a prime number that is greater than or equal to anInteger.  
 The prime number is not necessarily the smallest prime number that is 
 greater than or equal to anInteger.  For anInteger greater than our 
 highest selected prime, returns an odd number."

| primes prime hi lo mid |
primes := #( 3 5 7 11 17 19 23 29 37 53 73 107 157 233 347 503 751 
1009 1511 2003 3001 4001 5003 6007 7001 8009 9001 
10007 11003 12007 13001 14009 15013 16001 17011 18013 19001 
20011 21001 22003 23003 24001 25013 26003 27011 28001 29009 
30011 31013 32003 33013 34019 35023 36007 37003 38011 39019 
40009 41011 42013 43003 44017 45007 46021 47017 48017 49003 
50021 51001 52009 53003 54001 55001 56003 57037 58013 59009 
60013 61001 62003 63029 64007 65003 66029 67003 68023 69001 
70001 71011 72019 73009 74017 75011 76001 77003 78007 79031 
80021 81001 82003 83003 84011 85009 86011 87011 88001 89003 
90001 91009 92003 93001 94007 95003 96001 97001 98009 99013 
100003 101009 102001 103001 104003 224737 350377 479909 
611953 746773 882377 1020379 1159523 1299709 2750159 4256233 
5800079 7368787 8960453 10570841 12195257 13834103 15485863 
32452843 49979687 67867967 86028121 104395301 122949823 
141650939 160481183 ).

hi := primes size.
(anInteger > (primes at: hi)) 
  ifTrue: [
    ^ anInteger odd 
      ifTrue: [ anInteger ] 
      ifFalse: [ anInteger + 1 ]
  ].

lo := 0.
[       "Binary search for closest selected prime that is >= anInteger"
  mid := (hi + lo) // 2.
  prime := primes at: mid.
  anInteger <= prime
    ifTrue: [ hi := mid ]
    ifFalse: [ lo := mid ].
  hi - lo > 1
] untilFalse.

^ primes at: hi
%


category: 'Accessing'
method: Integer
denominator

"For an Integer, always returns 1."

^1
%

category: 'Accessing'
method: Integer
size: anInteger

"Disallowed.  You may not change the size of an Integer."

self shouldNotImplement: #size:
%

category: 'Accessing'
method: Integer
numerator

"For an Integer, always returns the receiver."

^self
%

category: 'Accessing'
method: Integer
_digitAt: anIndex

"Returns the value of an indexed variable in the receiver.  Fail if anIndex
 is not an Integer or is out of bounds."

<primitive: 18>

self _primitiveFailed: #_digitAt: .
self _uncontinuableError
%

category: 'Accessing'
method: Integer
_digitLength

"Returns the number of base 32768 digits in the receiver, without counting
 any leading zeros."

<primitive: 19>

self _primitiveFailed: #_digitLength .
self _uncontinuableError
%

category: 'Accessing'
method: Integer
_lastDigit

"Returns the last base 32768 digit of the receiver."

^self _digitAt: self _digitLength
%

category: 'Updating'
method: Integer
_digitAt: anIndex put: aValue

"Store aValue into the receiver's base 32678 digit specified by anIndex .
 indicated by index.  Fail if the value is negative or is larger than 32767.
 Fail if the index is not an Integer or is out of bounds.  Returns the value
 that was stored."

<primitive: 257>

anIndex _validateClass: SmallInteger.
aValue _validateClass: SmallInteger.
self _primitiveFailed: #_digitAt:Put: .
self _uncontinuableError
%

! Gs64 v2.0, deleted _growby: , no senders in image

category: 'Updating'
method: Integer
_growto: anInteger

""

| x size n byte |

(anInteger <= 0)
  ifTrue: [^0].
x := Integer _new: anInteger neg: (self negative).
(anInteger > (self _digitLength))
   ifTrue: [size := self _digitLength]
   ifFalse: [size := anInteger].
n := 1.
[n <= size]
   whileTrue: [
      byte := self _digitAt: n.
      x _digitAt: n put: byte.
      n := n + 1].
^ x
%

! deleted _lastDigitGet

category: 'Converting'
method: Integer
asFloat

"Returns a SmallDouble or Float representing the receiver."

<primitive: 138>

self _primitiveFailed: #asFloat .
self _uncontinuableError
%

category: 'Formatting'
method: Integer
asString

"Returns a string representing the receiver.  Positive
 values do not include a leading + ."


<primitive: 265>

self _primitiveFailed: #asString .
self _uncontinuableError
%

category: 'Converting'
method: Integer
asCharacter

"Returns the Character whose value equals the receiver.  Allowable range
 for the receiver is 0 to 65535, inclusive."

^ Character withValue: self
%

category: 'Converting'
method: Integer
asJISCharacter

"Returns the JISCharacter whose JIS value equals the receiver.  Allowable range
 for the receiver is 0 to 65535, inclusive."

^ JISCharacter withValue: self
%

category: 'Converting'
method: Integer
asDecimalFloat

"Returns a DecimalFloat representing the receiver."

"The actual implementation of this method is in bomlast.gs."

 self _uncontinuableError
%

category: 'Converting'
method: Integer
asFraction

"Returns a Fraction having a numerator equal to the receiver and a denominator
 of 1."

^ (Fraction new _setNumerator: self denominator: 1) immediateInvariant
%

category: 'Converting'
method: Integer
asInteger

"Returns the receiver."

^ self
%

category: 'Converting'
method: Integer
_coerce: aNumber

"Coerces an Integer."

^ aNumber truncated
%

category: 'Converting'
method: Integer
_generality

"Returns the generality of Integer."

^ 40
%

category: 'Comparing'
method: Integer
< anInteger

"Returns true if the receiver is less than anInteger; returns false otherwise."

<primitive: 20>

^ self _retry: #< coercing: anInteger
%

category: 'Comparing'
method: Integer
<= anInteger

"Returns true if the receiver is less than or equal to anInteger; returns false
 otherwise."

<primitive: 21>

^ self _retry: #<= coercing: anInteger
%

category: 'Comparing'
method: Integer
> anInteger

"Returns true if the receiver is greater than anInteger; returns false
 otherwise."

<primitive: 22>

^ self _retry: #> coercing: anInteger
%

category: 'Comparing'
method: Integer
>= anInteger

"Returns true if the receive is greater than anInteger; returns false
 otherwise."

<primitive: 23>

^ self _retry: #>= coercing: anInteger
%

category: 'Comparing'
method: Integer
= anInteger

"Returns true if the receiver is equal to anInteger; returns false otherwise."

<primitive: 24>

^ self _retry: #= coercing: anInteger
%

category: 'Comparing'
method: Integer
hash

"Returns a numeric hash index.  For an Integer representable in 30 bits,
 returns a SmallInteger equal to the receiver. "

<primitive: 530>
self _primitiveFailed: #hash .
self _uncontinuableError
%

category: 'Comparing'
method: Integer
~= anInteger

"Returns true if the receiver is not equal to anInteger; returns false
 otherwise."

<primitive: 25>

^ self _retry: #~= coercing: anInteger
%

category: 'Truncation and Rounding'
method: Integer
ceiling

"Returns the receiver."

^ self
%

category: 'Truncation and Rounding'
method: Integer
floor

"Returns the receiver."

^ self
%

category: 'Truncation and Rounding'
method: Integer
rounded

"Returns the receiver."

^ self
%

category: 'Truncation and Rounding'
method: Integer
truncated

"Returns the receiver."

^ self
%

category: 'Arithmetic'
method: Integer
+ anInteger

"Returns the sum of the receiver and anInteger."

<primitive: 258>

^ self _retry: #+ coercing: anInteger
%

category: 'Arithmetic'
method: Integer
- anInteger

"Returns the difference between the receiver and anInteger."

<primitive: 259>

^ self _retry: #- coercing: anInteger
%

category: 'Arithmetic'
method: Integer
* anInteger

"Returns the product of the receiver and anInteger."

<primitive: 260>

^ self _retry: #* coercing: anInteger
%

category: 'Arithmetic'
method: Integer
/ anInteger

"Returns the result of dividing the receiver by anInteger."

<primitive: 261>
(anInteger = 0)
  ifTrue: [^ self _errorDivideByZero].
(anInteger _isInteger)
  ifTrue: [^(Fraction numerator: self denominator: anInteger)]
  ifFalse: [^ self _retry: #/ coercing: anInteger]
%

category: 'Arithmetic'
method: Integer
quo: anInteger

"Divides the receiver by anInteger.  Returns the integer quotient, with
 truncation toward zero.  For example,

 -9 quo: 4 = -2

 The selector rem: returns the remainder from this division."

<primitive: 262>
(anInteger = 0)
  ifTrue: [^ self _errorDivideByZero].
(anInteger _isInteger)
  ifFalse: [^ self _retry: #quo: coercing: anInteger]
%

category: 'Arithmetic'
method: Integer
// anInteger

"Divides the receiver by anInteger.  Returns the integer quotient, with
 truncation toward negative infinity.  For example,

 9//4 = 2
 -9//4 = -3

 The selector \\ returns the remainder from this division."

<primitive: 263>
(anInteger = 0)
  ifTrue: [^ self _errorDivideByZero].
^ super // anInteger
%

category: 'Arithmetic'
method: Integer
\\ anInteger

"Returns the modulus defined in terms of //.  Returns a Number with the same
 sign as the argument anInteger.  For example,

 9\\4 = 1
 -9\\4 = 3
 9\\-4 = -3"

<primitive: 264>
(anInteger = 0)
  ifTrue: [^ self _errorDivideByZero].
^ super \\ anInteger
%

! fix 32816, 33317 , 33390
category: 'Divisibility'
method: Integer
gcd: anInteger

"Answer the greatest common divisor of the receiver and anInteger."

"Answer the largest non-negative integer that divides both the receiver
and anInteger with no remainder.
Answer 0 if the receiver and anInteger are both zero."

| divisor dividend remainder |
dividend := self abs.
anInteger _validateClass: Integer.
remainder := divisor := anInteger abs.
[remainder = 0] whileFalse: [
  remainder := dividend rem: divisor.
  dividend := divisor.
  divisor := remainder
].
^dividend
%


category: 'Divisibility'
method: Integer
lcm: anInteger

"Returns the least common multiple of the receiver and anInteger."

^ self // (self gcd: anInteger) * anInteger
%

category: 'Bit Manipulation'
method: Integer
allMask: anInteger

"Treats the argument anInteger as a bit mask.  Returns true if all of the bits
 that are 1 in the argument are 1 in the receiver; returns false otherwise."

^ anInteger = (self bitAnd: anInteger)
%

category: 'Bit Manipulation'
method: Integer
anyMask: anInteger

"Treats the argument anInteger as a bit mask.  Returns true if any of the bits
 that are 1 in the argument are 1 in the receiver; returns false otherwise."

^0 ~= (self bitAnd: anInteger )
%

! added  use of self + 0   to fix 33540
category: 'Bit Manipulation'
method: Integer
bitAnd: anInteger

"Returns an Integer whose bits are the logical and of the receiver's bits and
 the bits of anInteger."

| rec |
rec := self + 0 "handle subnormal Integer" .
rec _isSmallInteger ifTrue:[
  ^ rec bitAnd: anInteger
].
anInteger _validateClass: Integer.
^ rec _digitLogic: anInteger
      op: #bitAnd:
      length: (rec _digitLength max: anInteger _digitLength)
%

category: 'Bit Manipulation'
method: Integer
bitAt: i

"Returns the bit at the ith position of the receiver, where 0 is the least
 significant bit."

| temp digitIndex index |

i _validateClass: SmallInteger.
(i < 0)
  ifTrue: [^i _error: #rtErrArgNotPositive].

digitIndex := i // 15 + 1.  "15 bits per digit, get a small integer"

temp := self _digitAt: digitIndex.
self negative
ifTrue:
  [ temp := 32767 - temp.
    index := 1.
      [ (index < digitIndex) & ((self _digitAt: index) == 0) ]
      whileTrue:
        [ index := index + 1 ].
      index == digitIndex
      ifTrue:
        [ temp := temp + 1 ].
  ].

(temp bitAnd: (1 bitShift: i \\ 15 )) == 0
  ifTrue: [ ^0 ]
  ifFalse: [ ^1 ]
%

category: 'Bit Manipulation'
method: Integer
bitInvert

"Returns an Integer whose bits are the one's-complement of the receiver."

^ -1 - self
%

category: 'Bit Manipulation'
method: Integer
bitOr: anInteger

"Returns an Integer whose bits are the logical or of the receiver's bits and
 the bits of anInteger."

| rec |
rec := self + 0 "handle subnormal Integer" .
rec _isSmallInteger ifTrue:[
  ^ rec bitOr: anInteger
].
anInteger _validateClass: Integer.
^rec _digitLogic: anInteger
      op: #bitOr:
      length: (rec _digitLength max: anInteger _digitLength)
%

! changes to fix 34742
category: 'Bit Manipulation'
method: Integer
bitShift: anInteger

"Returns an Integer whose value (in two's-complement representation) is the
 receiver's value (also in two's-complement representation) shifted by
 anInteger bits.

 If anInteger is positive, the shift is to the left, and zero-bits enter at
 the right.  If anInteger is negative, the shift is to the right, and the sign
 bit is repeated at the left."

| result abs |
self _isSmallInteger ifFalse:[ | rec |
  rec := self + 0 .
  rec _isSmallInteger ifTrue:[
    "handle subnormal Integer"
    ^ rec bitShift: anInteger
  ].
].
anInteger _validateClass: SmallInteger.
(anInteger >= 0) ifTrue: [
  ^ (self _digitLshift: (anInteger \\ 15)
                  bytes: (anInteger // 15)
                  lookfirst: true) truncated
].
abs := 0 - anInteger.
result := (self _digitRshift: (abs \\ 15)
                bytes: (abs // 15)
                lookfirst: self _digitLength) truncated.
(self negative _and: [self _anyBitTo: abs]) ifTrue: [
   result := result - 1
].
^result
%

category: 'Bit Manipulation'
method: Integer
bitXor: anInteger

"Returns an Integer whose bits are the logical xor of the receiver's bits and
 the bits of anInteger."
| rec |
rec := self + 0 "handle subnormal Integer" .
rec _isSmallInteger ifTrue:[
  ^ rec bitXor: anInteger
].
anInteger _validateClass: Integer.
^rec _digitLogic: anInteger
      op: #bitXor:
      length: (rec _digitLength max: anInteger _digitLength)
%

category: 'Bit Manipulation'
method: Integer
highBit

"(Subclass responsibility.)  Returns the index of the high-order bit that is set
 in the binary representation of the receiver.  (If the receiver is a negative
 integer, takes its absolute value first.)  If the receiver is zero, this
 returns nil."

Integer subclassResponsibility: #highBit
%

category: 'Bit Manipulation'
method: Integer
noMask: anInteger

"Treats the argument anInteger as a bit mask.  Returns true if none of the bits
 that are 1 in the argument are 1 in the receiver; returns false otherwise."

^ 0 = (self bitAnd: anInteger)
%

category: 'Private'
method: Integer
_anyBitTo: pos

"Returns true if any bit from 1 to pos is non-zero, for testing for loss of
 significant bits when shifting right"

1 to: pos - 1 // 15 do:
  [:i | ((self _digitAt: i) ~~ 0) ifTrue: [^true]].
^(self _digitAt: pos + 14 // 15)
  anyMask: (#(1 3 7 15 31 63 127 255 511 1023 2047 4095 8191 16383 32767)
  at: pos - 1 \\ 15 + 1)
%

category: 'Private'
method: Integer
_digitLogic: arg op: op length: len

""

| result neg1 neg2 rneg z1 z2 rz b1 b2 b rdigits |
neg1 := self negative.
neg2 := arg negative.
rneg :=
   (((neg1)
      ifTrue: [-1]
      ifFalse: [0])
      perform: op
      with: ((neg2)
            ifTrue: [-1]
            ifFalse: [0])) < 0.
result := Integer _new: len neg: rneg.
rz := z1 := z2 := true.
rdigits := 1.
1 to: len do:
   [:i |
   b1 := self _digitAt: i.
   neg1
      ifTrue: [
         z1
            ifTrue: [
               (b1 == 0)
                  ifFalse: [
                     z1 := false.
                     b1 := 32768 - b1.
                  ].
            ]
            ifFalse: [b1 := 32767 - b1]
      ].
   b2 := arg _digitAt: i.
   neg2
      ifTrue: [
         z2
            ifTrue: [
               (b2 == 0)
                  ifFalse: [
                     z2 := false.
                     b2 := 32768 - b2.
                  ].
            ]
            ifFalse: [b2 := 32767 - b2]
      ].
   b := b1 perform: op with: b2.
   rneg
      ifTrue: [
         rz
            ifTrue: [
               (b = 0)
                  ifFalse: [
                     rz := false.
                     b := 32768 - b.
                  ].
            ]
            ifFalse: [b := 32767 - b]
      ].
   (b = 0)
      ifFalse: [rdigits := i].
   result _digitAt: i put: b.
].
(rdigits ~= result _digitLength)
  ifTrue: [^(result _growto: rdigits) truncated].
^result truncated
%

category: 'Private'
method: Integer
_digitLshift: n bytes: b lookfirst: a

""

| x f m len r digit |
"shift by 15*b+n bits, 0<=n<15.  a true means check for a leading zero byte
in the result "
x := 0.
f := n - 15.
m := 32767 bitShift: 0 - n.
len := self _digitLength + 1 + b.
(a _and: [(self _lastDigit bitShift: f) = 0])
   ifTrue: [len := len - 1].
r := Integer _new: len neg: self negative.
1 to: b do: [:i | r _digitAt: i put: 0].
1 to: len - b do:
   [:i |
   digit := self _digitAt: i.
   r _digitAt: i + b put: (((digit bitAnd: m) bitShift: n) bitOr: x).
   "Avoid values > 15 bits"
   x := digit bitShift: f].
^r
%

category: 'Private'
method: Integer
_digitRshift: anInteger bytes: b lookfirst: a

"Shift right 15*b+anInteger bits, 0<=anInteger<15.  Discard all digits
 beyond a, and all zeroes at or below a."

| n x i r f m digit count|
n := 0 - anInteger.
x := 0.
f := n + 15.
i := a.
m := 32767 bitShift: 0 - f.
digit := self _digitAt: i.
[((digit bitShift: n) bitOr: x) = 0 _and: [i ~~ 1]] whileTrue:
   [x := digit bitShift: f "Can't exceed 15 bits".
   i := i - 1.
   digit := self _digitAt: i].
(i <= b)
  ifTrue: [^0].  "All bits lost"
r := Integer _new: i - b neg: self negative.
count := i.
x := (self _digitAt: b + 1) bitShift: n.
b + 1 to: count do:
   [:i | digit := self _digitAt: i + 1.
   r _digitAt: i - b put: (((digit bitAnd: m) bitShift: f) bitOr: x)
      "Avoid values > 15 bits".
   x := digit bitShift: n].
^r
%

category: 'Converting'
method: Integer
asHexString

"Returns a String representing the receiver as a base-16 number."

| hex cp digits dig size begIdx endIdx |

hex := '0123456789abcdef'.
digits := String new.
cp := self < 0 ifTrue: [self * -1] ifFalse: [self].
[cp = 0] whileFalse: [
  dig := cp \\ 256.
  cp := cp // 256.
  digits add: (hex at: dig // 16 + 1); add: (hex at: dig \\ 16 + 1).
].

digits size == 0 ifTrue: [
  digits add: '00'.
  ^digits
].

"the bytes are now in reverse order and must be swapped around"
size := digits size.
1 to: digits size // 4 do: [:idx |
  begIdx := idx + idx - 1.
  endIdx := size - begIdx.
  dig := digits at: endIdx.
  digits at: endIdx put: (digits at: begIdx).
  digits at: begIdx put: dig.
  begIdx := begIdx + 1.
  endIdx := endIdx + 1.
  dig := digits at: endIdx.
  digits at: endIdx put: (digits at: begIdx).
  digits at: begIdx put: dig
].
self < 0 ifTrue: [
  digits insertAll: '-' at: 1
].
^digits
%

category: 'Flow of Control'
method: Integer
to: aNumber

"Returns an Array containing all Integers between the receiver and the
 argument."

| nums |

aNumber _validateClass: Integer.
nums := #[].
self to: aNumber do:
  [ :i | nums add: i ].

^nums
%


! removed: ! to: aNumber by: interval
! to fix 13332

category: 'Instance Creation'
classmethod: Integer
fromHexString: aString

"Returns an instance of the appropriate subclass of the receiver whose
 value is read from the given string."

| ch factor result idx size digit |

idx := 1.
size := aString size.
size > 0 ifTrue: [
  ch := aString at: idx.
  [ ch = $  ] whileTrue: [
    idx := idx + 1.
    ch := aString at: idx
  ].

  ch = $- ifTrue: [
    idx := idx + 1.
    factor := -1
  ]
  ifFalse: [
    ch = $+ ifTrue: [
      idx := idx + 1.
    ]
  ].
].

result := 0.

(idx > size _or: [(ch := aString at: idx) isDigit not
  _and: [(#($a $b $c $d $e $f $A $B $C $D $E $F) includesIdentical: ch) not]]) ifTrue: [
  ^ self _errIncorrectFormat: aString
].

[ idx > size _or: [ (ch := aString at: idx) isDigit not
  _and: [(#($a $b $c $d $e $f $A $B $C $D $E $F) includesIdentical: ch) not]
  ] ] whileFalse: [
  digit := ch > $9 ifTrue: [ch asUppercase asciiValue - $A asciiValue + 10]
                    ifFalse: [ ch asciiValue - $0 asciiValue ].
  result := result * 16 + digit.
  idx := idx + 1.
].

(ch isLetter
  _and: [(#($a $b $c $d $e $f $A $B $C $D $E $F) includesIdentical: ch) not]) 
  ifTrue: [
  ^ self _errIncorrectFormat: aString
].

factor ~~ nil ifTrue: [
  result := result * factor
].

^result
%

category: 'Instance Creation'
classmethod: Integer
fromStream: aStream

"Reads bytes from aStream and returns an instance of the appropriate subclass.
 Starting at the current position of aStream, leading blanks and trailing blanks
 are permitted.  Trailing non-digits terminate the conversion without raising
 any errors.

 Smalltalk radix syntax for non-base-10 numbers is supported."

| ch factor result radix leadingSign |

self _checkReadStream: aStream forClass: CharacterCollection.

ch := aStream next.
[ ch isEquivalent: $ ] whileTrue: [
  ch := aStream next
].
aStream position: (aStream position - 1).
result := 0.

leadingSign := false.
(aStream peek isEquivalent: $-)
ifTrue: [
  aStream next.
  factor := -1.
  leadingSign := true.
]
ifFalse: [
  (aStream peek isEquivalent: $+) ifTrue: [
    leadingSign := true.
    aStream next.
  ].
  factor := 1.
].

(aStream atEnd _or: [ aStream peek isDigit not]) ifTrue: [
  ^ self _errIncorrectFormat: aStream
].
[ aStream atEnd not _and: [ (ch := aStream peek) isDigit ] ] whileTrue: [
  aStream next.
  result := result * 10 + ch digitValue
].

(ch = $r _or: [ch = $#]) ifTrue: [
  "found a radix separator"
  aStream next.
  radix := result.
  result := 0.

  leadingSign ifTrue: [ ^ self _errIncorrectFormat: aStream ].
  "The sign should be after the radix separator."

  (aStream peek isEquivalent: $-)
    ifTrue: [ aStream next.  factor := -1 ]
    ifFalse: [
      (aStream peek isEquivalent: $+) 
        ifTrue: [ leadingSign := true.  aStream next ].
        factor := 1.
      ].

  [ aStream atEnd not _and: [ aStream peek isSeparator not ] ] whileTrue: [
    ch := aStream next.
    result := result * radix + (ch digitValueInRadix: radix).
  ]
].

^ result * factor
%

category: 'Arithmetic'
method: Integer
factorial

"Returns the factorial of the receiver.  Returns 1 if the
 receiver is less than or equal to 1."

| x result |
result := 1  .
x := result .
self timesRepeat:[ result := result * x .  x := x + 1 ] .
^ result .
%

category: 'Private'
method: Integer
_isLeapYear

"Returns true if the year represented by the value of the receiver is
 a leap year, false otherwise.  Valid at least for years 1900 and later."

 "Useful in debugging Date and DateTime."

(self \\ 100) == 0 ifTrue:[
   ^ (self \\ 400) == 0
   ].
^ (self \\ 4) == 0
%

category: 'Formatting'
method: Integer
printStringRadix: base

"Returns a String that describes the receiver in the specified radix."

^ self printStringRadix: base showRadix: true.
%

category: 'Formatting'
method: Integer
printStringRadix: base showRadix: aBoolean

"Returns a String that describes the receiver in the specified radix."

| aStream |

aStream := WriteStream on: (String new).
self printOn: aStream base: base showRadix: aBoolean.
^ aStream contents.
% 

category: 'Formatting'
method: Integer
printOn: aStream base: b

"Prints a representation of the receiver on aStream in base b.  The base b
 must be 2 <= b <= 36.  Returns the receiver."

^ self printOn: aStream base: b showRadix: true.
%

category: 'Formatting'
method: Integer
printOn: aStream base: b showRadix: aBoolean

"Prints a representation of the receiver on aStream in base b.  The base b
 must be 2 <= b <= 36.  Returns the receiver."

| x y absVal div temp digits |

(b between: 2 and: 36)
  ifFalse: [ ^ self _error: #rtErrInvalidArgument args: #[ b ]].

aBoolean
  ifTrue: [
    b printOn: aStream.
    aStream nextPut: $r.
    ].

self negative ifTrue: [ aStream nextPut: $- ].

absVal := self abs.

temp := 1.
[ temp <= absVal ]
  whileTrue: [ temp := b * temp ].

div := temp / b.

digits := #($0 $1 $2 $3 $4 $5 $6 $7 $8 $9
            $A $B $C $D $E $F $G $H $I $J 
            $K $L $M $N $O $P $Q $R $S $T 
            $U $V $W $X $Y $Z).

x := absVal.
[div > 0 ]
  whileTrue: [
    y := x quo: div.
    x := x rem: div.
    div := div quo: b.
    aStream nextPut: (digits at: (y + 1))
    ].

^ self
%
category: 'Private'
method: Integer
_floatParts

" Returns a 2 element Array describing receiver;
    first element is a Float , 
    second element is an Integer .
  The Float represents the most significant 53 bits
  of the receiver, rounded the same as  for Integer>>asFloat .
  The second element is the power of 2 describing the
  remaining bits of the receiver."

<primitive: 646>
self _primitiveFailed: #_floatParts .
self _uncontinuableError
%

category: 'Arithmetic'
method: Integer
raisedTo: aNumber

"Returns the receiver raised to the power of the argument."

| prod |
(aNumber isKindOf: Integer) ifFalse:[
  ^ self asFloat raisedTo: aNumber 
].
prod := 1 .
aNumber abs timesRepeat:[
  prod := prod * self .
].
aNumber < 0 ifTrue:[
 ^ 1 / prod 
].
^ prod
%

