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

Raymond Toy raymond.toy at ericsson.com
Thu Apr 6 09:11:44 EDT 2006


>>>>> "sjt" == Stephen J Turnbull <stephen at xemacs.org> writes:

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

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

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

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

If you don't get 1.0, you have a badly broken system, if you are using
IEEE 754.  0.125 and 0.875 can be represented exactly, and so can
their sum.  If you don't get 1.0, then your reader is broken or your
printer.  Or, perhaps, + is broken. :-)

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

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

But it is possible to do a better job.  There exist algorithms to read
decimals and produce closest representable IEEE number.  Likewise,
there are algorithms for printing IEEE numbers such that the resulting
output is the closest representation, and which, when read back,
produce *exactly* the same IEEE number.  CMUCL prints "8.18e-1"
exactly like that.

Perhaps printf/scanf doesn't use those algorithms.

Ray




More information about the XEmacs-Beta mailing list