[squeakdev] 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/SYSEXTRounding.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: [0]
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
receiver: self
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
 head guess floorLog10 
(self negative or: [self isZero])
ifTrue:
[^self class
raise: #domainErrorSignal
receiver: self
selector: #floorLog10
errorString: (#errLogNegativeNumber << #dialogs >> 'Can''t take
log of number <= 0')].
head := self.
floorLog10 := 0.
[head < 10] whileFalse: [
guess := ((head highBit  1) * 1233 bitShift: 12) max: 1. "This is
because (2 log)/(10 log)*4096 is slightly greater than 1233"
head := head // (10 raisedTo: guess).
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 
>
>
>
>
More information about the Squeakdev
mailing list
