|
From: | Noah Lavine |
Subject: | Re: Numeric improvements in stable-2.0 |
Date: | Wed, 20 Mar 2013 15:43:49 -0400 |
Hello all,
I wanted to briefly highlight some of the improvements to numerics that
I've recently pushed to stable-2.0.
* 'number->string' now reliably outputs enough digits to produce the
same number when read back in. Previously, it badly mishandled
subnormal numbers (printing them as "#.#"), and it also failed to
distinguish between unequal inexact numbers, e.g. with IEEE 64-bit
doubles, the successor of 1.0 is (+ 1.0 (expt 2.0 -52)), which
formerly printed as "1.0" even though it was not '=' to 1.0. Now it
prints as "1.0000000000000002".
These problems had far-reaching implications, since the compiler uses
'number->string' to serialize numeric constants into .go files, and
that includes constants derived by the partial evaluation pass of the
compiler. E.g. (* 1e-160 1e-160) evaluated to #f at the REPL (because
of the mishandling of subnormals), and a very precise value of PI
written as a constant in source code would be imprecisely serialized
in the .go file.
* 'exact->inexact' now guarantees correct IEEE rounding, i.e. it
reliably produces the closest representable double, with ties going to
even mantissas.
* 'sqrt' now produces an exact rational result whenever the input is an
exact square of a rational:
(sqrt 36/49) => 6/7
(sqrt #e1e-100) => 1/100000000000000000000000000000000000000000000000000
(sqrt #e1e100) => 100000000000000000000000000000000000000000000000000
(sqrt (expt 2 300)) => 1427247692705959881058285969449495136382746624
(sqrt 153440958974845354020314851471204/16857784036736598738708871009)
=> 12387128762342198/129837529384753
* 'sqrt' now handles exact rational inputs that are too large or too small
to be represented by an inexact:
(sqrt (expt 10 401)) => 3.1622776601683794e200 (previously +inf.0)
(sqrt (expt 10 -401)) => 3.1622776601683792e-201 (previously 0.0)
[as you can see, 'sqrt' still does not do correct IEEE rounding, but
that's a more difficult job that will have to wait until after 2.0.8]
* 'integer-expt' and 'expt' are now much faster when exponentiating
exact rationals (7-10 times faster in many cases).
Mark
[Prev in Thread] | Current Thread | [Next in Thread] |