guile-devel
[Top][All Lists]
Advanced

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

Numeric improvements in stable-2.0


From: Mark H Weaver
Subject: Numeric improvements in stable-2.0
Date: Wed, 20 Mar 2013 14:49:02 -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



reply via email to

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