[BUG] Fraction>>asFloat returns infinity if numerator and denominator both very large

Lex Spoon lex at cc.gatech.edu
Mon Oct 9 21:13:41 UTC 2000


The problem is that (10 raisedToInteger: 309) is too large to represent
as a float.  So sending asFloat to *it* gives infinity back.  Since this
happens on both the numerator and denominator, a more reasonable answer
would be NaN.

Writing the code so that you get 1.0 out of it is challenging, but it
would surely be nice.  Any numerics experts around?  I think you could
get a decent answer by:

	1. Right-shift each number until you only have as many digits as a
Float can represent.  Remember the amount each numbers was shifted.

	2. Divide the numbers.

	3. Shift the result, as needed.



In any case, getting Infinity out of this is bogus and is definately a
bug.

-Lex



Martin McClure <martin at hand2mouse.com> wrote:
> I ran into this surprising result last night:
> 
>    aFraction rounded
> 
> returned a reasonable value (318, IIRC) but
> 
>    aFraction asFloat
> 
> returned Infinity.
> 
> I dug a bit and found that the cause is that both the denominator and 
> numerator were very large.
> 
> A test case:
> 
>    ((10 raisedToInteger: 309) + 1 / (10 raisedToInteger: 309)) rounded
> 
> returns 1, which seems correct, but
> 
>    ((10 raisedToInteger: 309) + 1 / (10 raisedToInteger: 309)) asFloat
> 
> returns Infinity, which does not seem correct. I expect to get 
> exactly 1.0 in this case, since that is the Float value that most 
> closely approximates the Fraction's value.
> 
> Fraction>>asFloat reads:
> 
> asFloat
> 	"Answer a Float that represents the same value as does the receiver."
> 
> 	| df scaleFactor scaledDenominator |
> 	df _ denominator asFloat.
> 	^ df isInfinite
> 		ifTrue:
> 			["might be representable as a denormalized Float"
> 			scaleFactor _ 2 raisedToInteger: 53.
> 			scaledDenominator _ (denominator / 
> scaleFactor) rounded.
> 			numerator asFloat / scaleFactor asFloat / 
> scaledDenominator asFloat]
> 		ifFalse:
> 			[numerator asFloat / df]
> 
> 
> 
> This code assumes that if the denominator isInfinite, that the 
> numerator is *not* Infinite.  Scaling down both numerator and 
> denominator before converting would avoid this problem, but it's not 
> clear to me exactly how much to scale to avoid losing precision 
> unnecessarily.
> 
> If the more numerically-minded folks on the list have an opinion on 
> this, please send it, otherwise I'll give it more thought this 
> evening.
> 
> And a historical note: Andres found a problem in Fraction>>asFloat a 
> couple of years ago, copied below, which may or may not be the same 
> problem.
> 
> -Martin
> 
> At 10:08 PM -0300 11/30/98, sqrmax at cvtci.com.ar wrote:
> >Hi.
> >
> >I found a problem with Fraction>>asFloat. And I've found a part of the
> >problem. Integer>>asFloat for largeIntegers is broken. It can 
> >consider as few as
> >49 bits of data when fraction parts of floats are 52 + implicit bits long.
> >This can happen when the largeInteger in question is longer than 7 bytes. This
> >is fixed, and a faster asFloat was developed. It can be more than 20% faster
> >than its original counterpart, plus it answers correctly.
> >
> >But Fraction>>asFloat still needs work.
> >
> >I include my profiler so you can measure the difference with precision.
> >
> >Andres.





More information about the Squeak-dev mailing list