changed: #//
oops: when result is SmallInteger minVal,
an unnormalized largeInt was returned.
--- a/LargeInteger.st Fri Feb 26 21:06:04 2010 +0100
+++ b/LargeInteger.st Fri Feb 26 21:20:38 2010 +0100
@@ -468,7 +468,7 @@
The result is truncated toward negative infinity and negative,
if the operands signs differ.
The following is always true:
- (receiver // aNumber) * aNumber + (receiver \\ aNUmber) = receiver
+ (receiver // aNumber) * aNumber + (receiver \\ aNUmber) = receiver
"
|cls divMod quo abs "{ Class: SmallInteger }" n|
@@ -481,33 +481,38 @@
Use a special method for this case ...
"
(cls == SmallInteger) ifTrue:[
- abs := aNumber.
- abs := abs abs.
- (abs between:1 and:16r00ffffff) ifTrue:[
- divMod := self absFastDivMod:abs.
- ] ifFalse:[
- n := abs asLargeInteger.
- ].
+ abs := aNumber.
+ abs := abs abs.
+ (abs between:1 and:16r00ffffff) ifTrue:[
+ divMod := self absFastDivMod:abs.
+ ] ifFalse:[
+ n := abs asLargeInteger.
+ ].
] ifFalse:[
- "
- if the argument is not a largeInteger, coerce
- "
- (cls == self class) ifFalse:[
- ^ self retry:#// coercing:aNumber
- ].
- n := aNumber
+ "
+ if the argument is not a largeInteger, coerce
+ "
+ (cls == self class) ifFalse:[
+ ^ self retry:#// coercing:aNumber
+ ].
+ n := aNumber
].
divMod isNil ifTrue:[
- divMod := self absDivMod:n.
+ divMod := self absDivMod:n.
].
quo := divMod at:1.
(sign == aNumber sign) ifFalse:[
- "/ adjust for truncation if negative and there is a remainder ...
- quo := quo sign:-1.
- (divMod at:2) == 0 ifFalse:[
- ^ quo - 1
- ].
+ "/ adjust for truncation if negative and there is a remainder ...
+ "/ be careful: there is one special case to care for here:
+ "/ if quo is maxInt+1, the negation can be represented as a smallInt.
+ quo := quo sign:-1.
+ (divMod at:2) == 0 ifFalse:[
+ ^ quo - 1
+ ].
+ quo digitLength == SmallInteger maxBytes ifTrue:[
+ ^ quo compressed
+ ].
].
^ quo
@@ -4945,9 +4950,9 @@
!LargeInteger class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.198 2010-02-26 20:06:04 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.199 2010-02-26 20:20:38 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.198 2010-02-26 20:06:04 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/LargeInteger.st,v 1.199 2010-02-26 20:20:38 cg Exp $'
! !