[squeak-dev] The Trunk: Kernel-nice.691.mcz

commits at source.squeak.org commits at source.squeak.org
Tue May 22 20:15:45 UTC 2012


Nicolas Cellier uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-nice.691.mcz

==================== Summary ====================

Name: Kernel-nice.691
Author: nice
Time: 22 May 2012, 10:14:29.897 pm
UUID: f69b524f-83bb-4ef0-b084-e7a96dd5d33e
Ancestors: Kernel-eem.690, Kernel-nice.690

Grace period is over, publish and merge the changes for printing Floating point with fixed precision.

=============== Diff against Kernel-eem.690 ===============

Item was added:
+ ----- Method: Float>>absPrintExactlyOn:base:decimalPlaces:showTrailingFractionalZeros: (in category 'printing') -----
+ absPrintExactlyOn: aStream base: base decimalPlaces: placesDesired showTrailingFractionalZeros: showtrailingZeros
+ 	"Print my value on a stream in the given base with fixed number of digits after floating point.
+ 	When placesDesired are beyond Float precision, zeroes are appended.
+ 	When showtrailingZeros is false, the trailing zeroes after decimal point will be omitted.
+ 	If all fractional digits are zeros, the decimal point is omitted too.
+ 	Assumes that my value is strictly positive; negative numbers, zero, and NaNs have already been handled elsewhere.
+ 	Based upon the algorithm outlined in:
+ 	Robert G. Burger and R. Kent Dybvig
+ 	Printing Floating Point Numbers Quickly and Accurately
+ 	ACM SIGPLAN 1996 Conference on Programming Language Design and Implementation
+ 	June 1996.."
+ 
+ 	| significand exp baseExpEstimate r s mPlus mMinus scale roundingLowIncludesLimits roundingHighIncludesLimits d tc1 tc2 decPointCount slowbit shead delta |
+ 	self isInfinite ifTrue: [aStream nextPutAll: 'Infinity'. ^ self].
+ 	significand := self significandAsInteger.
+ 	exp := (self exponent - 52) max: MinValLogBase2.
+ 	exp >= 0
+ 		ifTrue:
+ 			[significand ~= 16r10000000000000
+ 				ifTrue:
+ 					[r := significand bitShift: 1 + exp.
+ 					s := 2.
+ 					mPlus := mMinus := 1 bitShift: exp]
+ 				ifFalse:
+ 					[r := significand bitShift: 2 + exp.
+ 					s := 4.
+ 					mPlus := 2 * (mMinus := 1 bitShift: exp)]]
+ 		ifFalse:
+ 			[(exp = MinValLogBase2 or: [significand ~= 16r10000000000000])
+ 				ifTrue:
+ 					[r := significand bitShift: 1.
+ 					s := 1 bitShift: 1 - exp.
+ 					mPlus := mMinus := 1]
+ 				ifFalse:
+ 					[r := significand bitShift: 2.
+ 					s := 1 bitShift: 2 - exp.
+ 					mPlus := 2.
+ 					mMinus := 1]].
+ 	delta := s / 2 / (base raisedTo: placesDesired).
+ 	roundingLowIncludesLimits :=  (mMinus < delta and: [mMinus := delta. true]) or: [significand even].
+ 	roundingHighIncludesLimits := (mPlus < delta and: [mPlus := delta. true]) or: [significand even].
+ 	baseExpEstimate := (self exponent * base asFloat reciprocalLogBase2 - 1.0e-10) ceiling.
+ 	baseExpEstimate >= 0
+ 		ifTrue: [s := s * (base raisedToInteger: baseExpEstimate)]
+ 		ifFalse:
+ 			[scale := base raisedToInteger: baseExpEstimate negated.
+ 			r := r * scale.
+ 			mPlus := mPlus * scale.
+ 			mMinus := mMinus * scale].
+ 	((r + mPlus >= s) and: [roundingHighIncludesLimits or: [r + mPlus > s]])
+ 		ifTrue: [baseExpEstimate := baseExpEstimate + 1]
+ 		ifFalse:
+ 			[r := r * base.
+ 			mPlus := mPlus * base.
+ 			mMinus := mMinus * base].
+ 	decPointCount := baseExpEstimate.
+ 	baseExpEstimate <= 0
+ 		ifTrue:
+ 			[placesDesired + baseExpEstimate <= 0
+ 				ifTrue:
+ 					[aStream nextPut: $0.
+ 					(showtrailingZeros and: [placesDesired > 0]) ifTrue: [aStream nextPut: $.; nextPutAll: (String new: placesDesired withAll: $0)].
+ 					^self].
+ 			aStream nextPutAll: '0.'; nextPutAll: (String new: 0 - baseExpEstimate withAll: $0)].
+ 	slowbit := 1 - s lowBit .
+ 	shead := s bitShift: slowbit.
+ 	[d := (r bitShift: slowbit) // shead.
+ 	r := r - (d * s).
+ 	(tc1 := (r <= mMinus) and: [roundingLowIncludesLimits or: [r < mMinus]]) |
+ 	(tc2 := (r + mPlus >= s) and: [roundingHighIncludesLimits or: [r + mPlus > s]])] whileFalse:
+ 		[aStream nextPut: (Character digitValue: d).
+ 		r := r * base.
+ 		mPlus := mPlus * base.
+ 		mMinus := mMinus * base.
+ 		(decPointCount := decPointCount - 1) = 0 ifTrue: [aStream nextPut: $.]].
+ 	tc2 ifTrue:
+ 		[(tc1 not or: [r * 2 >= s]) ifTrue: [d := d + 1]].
+ 	aStream nextPut: (Character digitValue: d).
+ 	decPointCount > 0
+ 		ifTrue:
+ 			[decPointCount - 1 to: 1 by: -1 do: [:i | aStream nextPut: $0].
+ 			(showtrailingZeros and: [placesDesired > 0]) ifTrue: [aStream nextPut: $.; nextPutAll: (String new: placesDesired withAll: $0)]]
+ 		ifFalse:
+ 			[(showtrailingZeros and: [placesDesired + decPointCount > 1]) ifTrue: [aStream nextPutAll: (String new: placesDesired + decPointCount - 1 withAll: $0)]].!

Item was changed:
+ ----- Method: Float>>absPrintOn:base:digitCount: (in category 'printing') -----
- ----- Method: Float>>absPrintOn:base:digitCount: (in category 'private') -----
  absPrintOn: aStream base: base digitCount: digitCount 
  	"Print me in the given base, using digitCount significant figures."
  
  	| fuzz x exp q fBase scale logScale xi |
  	self isInfinite ifTrue: [^ aStream nextPutAll: 'Inf'].
  	fBase := base asFloat.
  	"x is myself normalized to [1.0, fBase), exp is my exponent"
  	exp := 
  		self < 1.0
  			ifTrue: [self reciprocalFloorLog: fBase]
  			ifFalse: [self floorLog: fBase].
  	scale := 1.0.
  	logScale := 0.
  	[(x := fBase raisedTo: (exp + logScale)) = 0]
  		whileTrue:
  			[scale := scale * fBase.
  			logScale := logScale + 1].
  	x := self * scale / x.
  	fuzz := fBase raisedTo: 1 - digitCount.
  	"round the last digit to be printed"
  	x := 0.5 * fuzz + x.
  	x >= fBase
  		ifTrue: 
  			["check if rounding has unnormalized x"
  			x := x / fBase.
  			exp := exp + 1].
  	(exp < 6 and: [exp > -4])
  		ifTrue: 
  			["decimal notation"
  			q := 0.
  			exp < 0 ifTrue: [1 to: 1 - exp do: [:i | aStream nextPut: ('0.0000'
  at: i)]]]
  		ifFalse: 
  			["scientific notation"
  			q := exp.
  			exp := 0].
  	[x >= fuzz]
  		whileTrue: 
  			["use fuzz to track significance"
  			xi := x asInteger.
  			aStream nextPut: (Character digitValue: xi).
  			x := x - xi asFloat * fBase.
  			fuzz := fuzz * fBase.
  			exp := exp - 1.
  			exp = -1 ifTrue: [aStream nextPut: $.]].
  	[exp >= -1]
  		whileTrue: 
  			[aStream nextPut: $0.
  			exp := exp - 1.
  			exp = -1 ifTrue: [aStream nextPut: $.]].
  	q ~= 0
  		ifTrue: 
  			[aStream nextPut: $e.
  			q printOn: aStream]!

Item was added:
+ ----- Method: Float>>printOn:maxDecimalPlaces: (in category 'printing') -----
+ printOn: aStream maxDecimalPlaces: placesDesired
+ 	"Refine super implementation in order to avoid any rounding error caused by rounded or roundTo:"
+ 	
+ 	self isFinite ifFalse: [^self printOn: aStream].
+ 	self > 0.0
+ 		ifTrue: [self absPrintExactlyOn: aStream base: 10 decimalPlaces: placesDesired showTrailingFractionalZeros: false]
+ 		ifFalse:
+ 			[self sign = -1
+ 				ifTrue: [aStream nextPutAll: '-'].
+ 			self = 0.0
+ 				ifTrue: [aStream nextPutAll: '0.0']
+ 				ifFalse: [self absPrintExactlyOn: aStream base: 10 decimalPlaces: placesDesired showTrailingFractionalZeros: false]]!

Item was added:
+ ----- Method: Float>>printOn:showingDecimalPlaces: (in category 'printing') -----
+ printOn: aStream showingDecimalPlaces: placesDesired
+ 	"Refine super implementation in order to avoid any rounding error caused by rounded or roundTo:"
+ 	
+ 	self isFinite ifFalse: [^self printOn: aStream].
+ 	self > 0.0
+ 		ifTrue: [self absPrintExactlyOn: aStream base: 10 decimalPlaces: placesDesired showTrailingFractionalZeros: true]
+ 		ifFalse:
+ 			[self sign = -1
+ 				ifTrue: [aStream nextPutAll: '-'].
+ 			self = 0.0
+ 				ifTrue: [aStream nextPutAll: '0.0']
+ 				ifFalse: [self absPrintExactlyOn: aStream base: 10 decimalPlaces: placesDesired showTrailingFractionalZeros: true]]!

Item was removed:
- ----- Method: Float>>printShowingDecimalPlaces: (in category 'printing') -----
- printShowingDecimalPlaces: placesDesired
- 	"This implementation avoids any rounding error caused by rounded or roundTo:"
- 	
- 	self isFinite ifFalse: [^self printString].
- 	^self asTrueFraction printShowingDecimalPlaces: placesDesired!



More information about the Squeak-dev mailing list