[squeak-dev] Re: Speeding up Float Numbers reading

nicolas cellier ncellier at ifrance.com
Tue Mar 11 11:42:11 UTC 2008


Andreas Raab <andreas.raab <at> gmx.de> writes:

> 
> nicolas cellier wrote:
> > A difference is that SqNumberParser does return the nearest floating 
> > point value, while ReadStream>>nextFloat does return an approximate. 
> > This explains some of the bad scores of the former which cannot avoid 
> > LargeInteger arithmetic when the latter does (cases of exponent with 
> > high values).
> 
> Interesting. Do you have an example for this? I went to great length to 
> ensure that #nextFloat answers consistent results to Float>>readFrom: 
> (otherwise I could have optimized various cases even more aggressively) 
> so I'd be interested in seeing cases where it differs.
> 
> Test cases would probably be best but in absence of those some general 
> guidance about how to create the problem would be appreciated.
> 

Hi Andreas,
If you say nextFloat implementation is bit identicle, i trust you.
What i do not trust is Number class>>readFrom: to answer nearest Floating point.
It cumulates several rounding errors (see below).

An example is this one:

self assert:
((SqNumberParser parse: '1.2345678901234567980') asTrueFraction
  - (12345678901234567980/10000000000000000000)) abs
< 
((Number readFrom: '1.2345678901234567980') asTrueFraction
  - (12345678901234567980/10000000000000000000)) abs.


You need a 3.9/3.10 image or patches from:
http://bugs.squeak.org/view.php?id=3564
http://bugs.squeak.org/view.php?id=3568
http://bugs.squeak.org/view.php?id=3512

Or you can just play with asTrueFraction:
(SqNumberParser parse: '1.2345678901234567980') asTrueFraction
  storeStringBase: 16.
'(16r13C0CA428C59FB/16r10000000000000)'

(Number readFrom: '1.2345678901234567980') asTrueFraction
  storeStringBase: 16.
'(16r4F03290A3167F/16r4000000000000)'
This is a one bit difference - multiply num and den by 4:
'(16r13C0CA428C59FC/16r10000000000000)'

Sure we can construct some cases with 2 bits off or more given the number of
successive inexact operations:

fraction := fractionPart asFloat
    "asFloat is inexact at about 15 decimal digits"
/ (base raisedTo: aStream position - fracpos).
  "10 raisedTo: is inexact if more than 23 digits
  (with asFloat patch, otherwise worse), and division is inexact too"

fractionDigits := aStream position - fracpos.
value := value asFloat + fraction.
  "Addition is inexact, that's already fourth
inexact operation before exponent operation"

And lastly:

baseValue * (base raisedTo: exp)
  "That's two more inexact ops, implicit asFloat conversion if exponent > 23,
  or negative, and Float multiply"

Nicolas




More information about the Squeak-dev mailing list