
On Mon, 27 Oct 2008, Ketil Malde wrote:
Of course, Haskell should discard the rather tasteless IEEE754 crud, and do its calculations on infinite streams of digits. Then, rounding upwards after 'take'ing a sufficient amount of decimals will be the right thing to do.
When I implemented just this in http://darcs.haskell.org/numericprelude/src/Number/Positional.hs I used redundant sets of digits. In a base-n number I use the digits 1-n to n-1. That is, the truncated number abc.def actually represents the interval [abc.def-0.001, abd.def+0.001]. This representation is not unique (more non-unique than standard base-n representation), but testing numbers with infinitely many places for equality is not possible anyway. So (==) is obsolete, just like for floating point numbers. The advantage is that carries are reduced considerably. It allows to compute (sqrt 2)^2, which is not possible in standard representation, because one can never decide whether the result is 2.00000... or 1.99999.... (Pentium's division algorithm also uses digits -1, 0, 1 (we could call them mone (minus one), none, one) for reduced carries.) In this redundant representation one could simply round by truncation, the result depends on the particular sequence of digits used to represent a number, and the rounding would not become worse by repeated rounding (also because it is already worse than the Haskel 98 rounding since the error with respect to the last digit is not only 0.5 but up to 1 :-).