[squeak-dev] The Inbox: Kernel-dtl.1166.mcz

commits at source.squeak.org commits at source.squeak.org
Thu Apr 26 02:48:59 UTC 2018


David T. Lewis uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-dtl.1166.mcz

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

Name: Kernel-dtl.1166
Author: dtl
Time: 25 April 2018, 10:48:38.572237 pm
UUID: 43d80609-fbc5-40a1-9d49-37d2c4f0b306
Ancestors: Kernel-dtl.1165

In calculation of asApproximateFraction, the digit count for floatPrecision should be
an integer, so do not convert it with asFlloat.

Allows the following to be resolved without infinite loop on comparison to Float infinity:
	((FloatArray new: 1) at: 1 put: 1 / 3; at: 1) asApproximateFractionFloatPrecision: 10000

=============== Diff against Kernel-dtl.1165 ===============

Item was changed:
  ----- Method: Float>>asApproximateFractionAtOrder:floatPrecision: (in category 'converting') -----
  asApproximateFractionAtOrder: maxOrder floatPrecision: decimalPlaces
  	"Answer a Fraction approximating the receiver. This conversion uses the 
  	continued fraction method to approximate a floating point number. If maxOrder
  	is zero, use maximum order. Assume that I am a float with decimalPlaces of
  	meaningful accuracy, regardless of the precision of my internal representation."
  
  	| num1 denom1 num2 denom2 int frac newD temp order floatPrecision |
  	num1 := self asInteger.	"The first of two alternating numerators"
  	denom1 := 1.		"The first of two alternating denominators"
  	num2 := 1.		"The second numerator"
  	denom2 := 0.		"The second denominator--will update"
  	int := num1.		"The integer part of self"
  	frac := self fractionPart.		"The fractional part of self"
  	order := maxOrder = 0 ifTrue: [-1] ifFalse: [maxOrder].
+ 	floatPrecision := 10 raisedTo: decimalPlaces.
- 	floatPrecision := (10 raisedTo: decimalPlaces) asFloat.
  	[frac = 0 or: [order = 0] ]
  		whileFalse: 
  			["repeat while the fractional part is not zero and max order is not reached"
  			order := order - 1.
  			newD := 1.0 / frac.			"Take reciprocal of the fractional part"
  			int := newD asInteger.		"get the integer part of this"
  			frac := newD fractionPart.	"and save the fractional part for next time"
  			temp := num2.				"Get old numerator and save it"
  			num2 := num1.				"Set second numerator to first"
  			num1 := num1 * int + temp.	"Update first numerator"
  			temp := denom2.				"Get old denominator and save it"
  			denom2 := denom1.			"Set second denominator to first"
  			denom1 := int * denom1 + temp.		"Update first denominator"
  			floatPrecision < denom1
  				ifTrue: 
  					["Is ratio past float precision?  If so, pick which 
  					of the two ratios to use"
  					num2 = 0.0 
  						ifTrue: ["Is second denominator 0?"
  								^ Fraction numerator: num1 denominator: denom1].
  					^ Fraction numerator: num2 denominator: denom2]].
  	"If fractional part is zero, return the first ratio"
  	denom1 = 1
  		ifTrue: ["Am I really an Integer?"
  				^ num1 "Yes, return Integer result"]
  		ifFalse: ["Otherwise return Fraction result"
  				^ Fraction numerator: num1 denominator: denom1]!



More information about the Squeak-dev mailing list