[Bug: 21.4.19] Bruised floating point numbers from string-to-int

Stephen J. Turnbull stephen at xemacs.org
Mon Apr 3 23:48:46 EDT 2006


Executive summary:

It's just a bad idea to print floating point numbers in their natural
representation, i.e., `(format "%s" x)'; alway use `(format "%f" x)'
(usually with a precision specifier):

(format "%5.3f" (string-to-number "8.180E-1")) => "0.818"

Plain "%f" has some default precision, but it's probably too wide for
most tables

(format "%f" (string-to-number "8.180E-1")) => "0.818000"

>>>>> On 4/3/06, Rodney Sparapani <rsparapa at mcw.edu> wrote:

    >> string-to-int sometimes returns unsightly values which makes
    >> writing elisp functions that operate on tables of numbers very
    >> complicated if you want them to remain easy on the eyes.  I'm
    >> not sure where the problem is: xemacs, os, compiler, cpu???

Welcome to floating point!  All hope abandon, ye who enter here.

Please note that *all* floating values are unsightly, containing a
53-bit mantissa where IEEE 754 doubles are used (about 16 digits, as
in your example).  As a matter of historical practice, most standard
libraries truncate trailing zeros when printing.  VC++ apparently
applies some kind of heuristic to "simplify" trailing nines as well.
However, there are always going to be examples that produce what you
consider bad behavior.  In fact, consider

(format "%s" (+ 0.125 0.875)) => "1.0"

I bet you would want 1.000, no?  You just can't win.

    >> Any help would be appreciated: (string-to-int "8.180E-1")
    >> 0.8179999999999999

IEEE 754 standard floating point is specified so that integers of
sufficiently low precision will always be represented exactly.
However, there's no guarantee that *any* fraction will be represented
exactly, by design.  (And of course an integer with more precision
than the floating point representation provides is not represented
exactly.)  This implies that it is not possible to round-trip
string->number->string.  The point is to allow efficient
*calculations* on various architectures.  "Printed representation is
not my job, mon!"

Your architecture evidently uses a binary representation, so "most"
decimal fractions cannot be represented exactly.

>>>>> "vin" == Vin Shelton <acs at xemacs.org> writes:

    vin> Interestingly, on my windows native XEmacs (both 21.4 and
    vin> 21.5), compiled with Visual C++, I get:

    vin> (string-to-int "8.180E-1") 0.818

    vin> On my Cygwin XEmacs (both 21.4 and 21.5), compiled with gcc,
    vin> I get:

    vin> (string-to-int "8.180E-1") 0.8179999999999999

Yup.  `string-to-int' is an alias for `string-to-number', which is
(ultimately) just a wrapper around the platform's printf implementation.
What you get is what you get.

-- 
School of Systems and Information Engineering http://turnbull.sk.tsukuba.ac.jp
University of Tsukuba                    Tennodai 1-1-1 Tsukuba 305-8573 JAPAN
               Ask not how you can "do" free software business;
              ask what your business can "do for" free software.




More information about the XEmacs-Beta mailing list