[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: [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 Squeak-dev mailing list