changed: #//
authorClaus Gittinger <cg@exept.de>
Fri, 26 Feb 2010 21:20:38 +0100
changeset 12747 0b1eae8de7a4
parent 12746 10866527a1ab
child 12748 0092049ca4d1
changed: #// oops: when result is SmallInteger minVal, an unnormalized largeInt was returned.
LargeInteger.st
--- 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 $'
 ! !