'From Squeak3.10beta of 22 July 2007 [latest update: #7159] on 24 March 2008 at 5:08:58 pm'!
"Change Set: Number-printShowingDecimalPlace-Patch-M5640-nice
Date: 24 March 2008
Author: nice
This is a new patch for http://bugs.squeak.org/view.php?id=5640
Patch accepted in squeak 3.10 is better, but still has problems.
Float>>rounded and Float>>roundTo: might cause rounding errors...
And also overflow.
Solution is to use Float>>asTrueFraction and avoid inexact arithmetic.
Also avoid (Utilities floatPrecisionForDecimalPlaces:) and perform all in exact arithmetic.
I also replaced #asInteger by #truncated in Number implementation though equivalent in Squeak.
Some dialects understand asInteger as rounded, and here we explicitely want truncated."!
!Number methodsFor: 'printing' stamp: 'nice 3/24/2008 16:54'!
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. It now handles negative numbers between 0 and -1 and rounds correctly in more cases. This method probably could be optimized -- improvements welcomed. Category was/is 'converting' but should be 'printing' "
| 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: #right 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: 2
-0.98 printShowingDecimalPlaces: 2
2.567 printShowingDecimalPlaces: 2
-2.567 printShowingDecimalPlaces: 2
0 printShowingDecimalPlaces: 2
Number categoryForSelector: #printShowingDecimalPlaces:
"! !
!Float methodsFor: 'printing' stamp: 'nice 3/24/2008 16:56'!
printShowingDecimalPlaces: placesDesired
"This implementation avoids any rounding error caused by rounded or roundTo:"
^self asTrueFraction printShowingDecimalPlaces: placesDesired! !