Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> This result is strictly a result of floating point math.

This specific result is a result of binary floating point math with a particular precision. More precision, or decimal floating point, will fix that, but have similar kinds of errors for the same operation on different numbers. fixed-size BCD/fixed-point math has other limitations, its not a general solution.

The general solution is to have a numeric tower where representations and operations meet the following rules:

1. The default representation of any exact literal (without a modifier representing a particular inexact representation, e.g., as an optimization or a necessity of interfacing with an external library) is exact,

2. Any operation on any operations between exact representations that can be done exactly is unless specified otherwise (as it might be for the same reasons discussed above), and stored in a representation that can represent the result exactly.

3. Essentially inexact operations or operations on inexact numbers are conducted in a way and produce output representations that minimize additional imprecision introduced, except when explicitly specified otherwise.

Computer algebra systems where the “top level representation is symbolic are potentially the ultimate expression of this, but the Scheme numeric tower is pretty good (but at least Racket, and I think schemes in general, represent exact decimal fractions as floats still, so don’t entirely avoid the problem, but at least division of integers produces exact rationals.) Lots of languages default to putting numbers expressed as literals into either fixed-sized integers (not bad, especially when those are often 64-bit now which rarely has much practical distinction from arbitrary precision in most applications) or fixed-sized binary floats (which are more problematic, especially given the mismatch between clean binary and clean decimal representations.) This is very good for efficiency, because computers can process fixed sized integers and binary floats very quickly. But, especially for floats, it can be bad for correctness when doing arithmetic where the input is all clean decimal literals.



Yes, Scheme has the concept of exactness[0]. In most Schemes, (exact? 2.3) ==> #f. But at least the exact? procedure exists. It can tell you whether your result might have been affected by these problems. If you want perfect answers, you can always use the rationals that are built into Scheme implementations with the full numeric tower.

[0] https://standards.scheme.org/corrected-r7rs/r7rs-Z-H-8.html#...


(inexact->exact x) and (exact->inexact x).


What about them?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: