 [squeak-dev] Rounding to n significant digits?

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Thu Aug 4 09:57:39 UTC 2011

I have a similar roundToDigts: in VW cincom public store
http://www.cincomsmalltalk.com/publicRepository/SYSEXT-Rounding.html
But your selector is even better, more explicit.
I can't say implementation is good, because rounding the value is
inexact in Float...

Integer>>roundToDigits: nDigits
^self isZero
ifTrue: 
ifFalse: [self roundTo: (10 raisedToInteger: (0 max: self abs
floorLog10 + 1 - nDigits))]

Fraction>>roundToDigits: nDigits
^self roundTo: (10 raisedToInteger: self abs floorLog10 + 1 - nDigits)

LimitedPrecisionReal>>roundToDigits: nDigits
"Warning: result might be inexact."

^self coerce: (self asFraction roundToDigits: nDigits)

FixedPoint>>roundToDigits: nDigits
^(self asRational roundToDigits: nDigits) asFixedPoint: scale

Fraction>>floorLog10
(numerator negative or: [numerator isZero])
ifTrue:
[^self class
raise: #domainErrorSignal
selector: #floorLog10
errorString: (#errLogNegativeNumber << #dialogs >> 'Can''t take
log of number <= 0')].
^ numerator >= denominator
ifTrue: [(numerator // denominator) floorLog10]
ifFalse:
["Assume fraction is normalized and handle 10 raised to a negative
integer power"
-1 + (numerator = 1
ifTrue: [denominator - 1]
ifFalse: [denominator // numerator]) floorLog10 negated ]

Integer>>floorLog10
(self negative or: [self isZero])
ifTrue:
[^self class
raise: #domainErrorSignal
selector: #floorLog10
errorString: (#errLogNegativeNumber << #dialogs >> 'Can''t take
log of number <= 0')].
floorLog10 := 0.
guess := ((head highBit - 1) * 1233 bitShift: -12) max: 1. "This is
because (2 log)/(10 log)*4096 is slightly greater than 1233"
floorLog10 := floorLog10 + guess].
^ floorLog10

Nicolas

2011/8/4 Bert Freudenberg <bert at freudenbergs.de>:
> Hi,
>
> I'd like to print decimal Floats with at most n significant digits. E.g.
>
>        123456 roundToSignificantDigits: 3
>        => 123000
>        0.00123456 roundToSignificantDigits: 3
>        => 0.00123
>
> Would this generally be useful? If so, what would a good selector be? And what a good implementation? Instead of rounding I'd be happy to just get a String.
>
> Thanks :)
>
> - Bert -
>
>
>
>