guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: numeric tests


From: Dirk Herrmann
Subject: Re: numeric tests
Date: Sat, 28 Jul 2001 04:21:18 +0200 (MEST)

On Thu, 19 Apr 2001, Dirk Herrmann wrote:

> On Wed, 4 Apr 2001, Bill Schottstaedt wrote:
> 
> > Out of mild curiousity, I translated some of Clisp's numerical tests
> > (released under GPL in Clisp, so presumably this is ok) to Scheme
> > using the "pass-if" style of Guile's tests, and noticed some odd
> > cases.  I spot-checked some of the worst looking results in
> > gmp-3.0.1's pexpr program which agreed with Clisp (i.e. that the test
> > should return 0).  For example, test 313, guile=8192.0, 335 got 5+e123
> > etc.  In case there's interest (some of the tests are a bit nutty),
> > the file is at ccrma-ftp.stanford.edu/pub/Lisp/number-tests.scm.
> 
> The problems seem to come from the fact, that the reader, as soon as it
> sees an expression like <digits>/<digits>, will use a floating point
> variable while parsing the digits.  This can lead to inaccuracies during
> parsing, because the construction of the floating point number itself
> takes a number of potentially inaccurate floating point operations.  In
> contrast, (/ <digits> <digits>) will first read two exact integers, and
> after that will perform a division to produce a floating point value.  
> Thus, any possible inaccuracy comes from the single final divide
> operation.

I have re-implemented the string->number functionality to (hopefully)
closely match the syntax as it is specified by R5RS.  The new
implementation tries to be as accurate as possible, i. e. a rational
number a/b is first read as two exact integers, and afterwards one single
division is performed.  This should solve the problem above.  
Unfortunately, I could not access the file with the tests any more.  Bill,
do you have a version of that file somewhere?

Just some more remarks:  The new implementation in its current state is
much slower than the old one.  I have at first aimed at correctness and
did not put a lot of effort into performance.  Should I commit it to the
CVS trunk anyway?  I don't promise to tune it up in the near future, but
maybe someone else would like to do it.  It is IMO easier to understand
than the old solution, which means that tuning it up would not be too
complicated.  It may well be, however, that the new way of parsing (with
the improved accuracy) just needs to be slower, and for the sake of
correctness we simply will have to live with it.

Despite the bad news with respect to performance, the new implementation
deals the following numbers correctly (try the current guile to see what
you get with the old implementation :-):  "#o777777" gives 262143,
"address@hidden" is not accepted as a number, neither is "5#.0".  However,
"#e9/10" _is_ accepted and gives 1, similarly "#e1.2" is accepted as well
and also gives 1 (to try these last two examples you will have to use
string->number explicitly, just typing them on the command line does not
work - #e seems to be overloaded by the uniform vector implementation).  

I was not quite sure about the last two examples "#e9/10" and "#e1.2".  
R5RS does not state that the #e prefix in conjunction with an inexact
number should be disallowed.  Thus, I interpret the #e prefix to "force"
exactness on the value, just like #i "forces" inexactness.  One reason why
I believe this interpretation makes sence is, that you might write a
number as 1.2, and still want it to be considered exact - 1.2 can be seen
as an alternative way to write 6/5, which would be interpreted as an exact
value anyway.  Thus, using the #e prefix, one could write #e1.2 and thus
express that this value should be interpreted as if 6/5 had been written.

However, for guile this means, that "#e1.2" gives 1, because the closest
exact value for 1.2 is 1 - I am using inexact->exact here.  Hmmm?

Best regards,
Dirk Herrmann




reply via email to

[Prev in Thread] Current Thread [Next in Thread]