
The Haskell 2010 report defines, in chapter 9, round :: (Real a, Fractional a, Integral b) => a -> b round x = let (n, r) = properFraction x -- n = truncate x, r = x-n (same sign as x) m = if r < 0 then n - 1 else n + 1 in case signum (abs r - 0.5) of -1 -> n -- round in if |r| < 0.5 1 -> m -- round out if |r| > 0.5 0 -> if even n then n else m (commented and slightly rearranged). The traditional definition of rounding to integer, so traditional that it is actually given in the OED, is basically round x = truncate (x + signum x * 0.5) There was a discussion of rounding recently in another mailing list and I put together this table: * Round x.5 OUT Ada, Algol W, C, COBOL, Fortran, Matlab, Pascal, PL/I, Python, Quintus Prolog, Smalltalk. The pre-computing tradition. * Round x.5 to EVEN Common Lisp, R, Haskell, SML, F#, Wolfram Language. * Round x.5 UP to positive infinity Java, JavaScript, ISO Prolog, Algol 60 * Rounding of x.5 UNSPECIFIED Algol 68, IMP 77 What I was wondering was whether anyone on this list knew why Haskell has the break-ties-to-even definition instead of the traditional break-ties-out one. (And please don't say that it is to get statistical unbiasedness, because given the kinds of data distribution I see, it _isn't_ unbiased.)

On 2 June 2015 at 04:08,
The Haskell 2010 report defines, in chapter 9, round :: (Real a, Fractional a, Integral b) => a -> b
round x = let (n, r) = properFraction x -- n = truncate x, r = x-n (same sign as x) m = if r < 0 then n - 1 else n + 1 in case signum (abs r - 0.5) of -1 -> n -- round in if |r| < 0.5 1 -> m -- round out if |r| > 0.5 0 -> if even n then n else m
(commented and slightly rearranged). The traditional definition of rounding to integer, so traditional that it is actually given in the OED, is basically
round x = truncate (x + signum x * 0.5)
There was a discussion of rounding recently in another mailing list and I put together this table:
* Round x.5 OUT Ada, Algol W, C, COBOL, Fortran, Matlab, Pascal, PL/I, Python, Quintus Prolog, Smalltalk. The pre-computing tradition.
* Round x.5 to EVEN Common Lisp, R, Haskell, SML, F#, Wolfram Language.
* Round x.5 UP to positive infinity Java, JavaScript, ISO Prolog, Algol 60
* Rounding of x.5 UNSPECIFIED Algol 68, IMP 77
What I was wondering was whether anyone on this list knew why Haskell has the break-ties-to-even definition instead of the traditional break-ties-out one. (And please don't say that it is to get statistical unbiasedness, because given the kinds of data distribution I see, it _isn't_ unbiased.)
This is pure conjecture, but reading about "round half to even" on Wikipedia (http://en.wikipedia.org/wiki/Rounding#Round_half_to_even) shows that it has the most aliases of all tie-breaking strategies, it is also the rounding used in IEEE 754. /M -- Magnus Therning OpenPGP: 0xAB4DFBA4 email: magnus@therning.org jabber: magnus@therning.org twitter: magthe http://therning.org/magnus

On 2/06/2015, at 7:30 pm, Magnus Therning
This is pure conjecture, but reading about "round half to even" on Wikipedia (http://en.wikipedia.org/wiki/Rounding#Round_half_to_even) shows that it has the most aliases of all tie-breaking strategies, it is also the rounding used in IEEE 754.
I'm not really interested in "pure conjecture" at this point. For what it's worth, in my copy of IEEE 754 it says <quote> 5.4. Conversion Between Floating-Point and Integer Formats It shall be possible to convert between all supported floating-point formats and all supported integer formats. Conversion to integer shall be effected by rounding as specified in Section 4. Conversions between floating-point integers and integer formats shall be exact unless an exception arises as specified in 7.1. 5.5. Round Floating-Point Number to Integer Value It shall be possible to round a floating-point number to an integral valued floating-point number in the same format. The rounding shall be as specified in Section 4, with the understanding that when rounding to nearest, if the difference between the unrounded operand and the rounded result is exactly one half, the rounded result is even. </quote> Section 4 specifies round-to-nearest-breaking-ties-to-even, round-to-plus-infinity, round-to-minus-infinity, and round-to-zero. Reading closely, we see that 5.4: it must be *possible* to convert between any size of float and any size of integer using any one of the four rounding rules at the user's choice. So the *effects* of RealFrac's {floor, ceiling, truncate, round} are required, but not those specific names. 5.5: it must be possible to convert any size of float to integer in the same format. This is subject to the current rounding mode. C's rint{,l,f} function does this. If there is anything in Haskell 2010 that meets the requirements of section 5.5, I have been unable to find it. Since IEEE 754 conformance is not a goal of Haskell (there is, for example, no way in Haskell 2010 to set the rounding direction), there has to be some *other* reason than IEEE conformance to explain the adoption of the break-ties-to-even rule for rounding. In any case, good support for IEEE 754 arithmetic since C99 hasn't stopped C providing rounding functions with the traditional semantics *as well as* ones with IEEE semantics.
participants (3)
-
Magnus Therning
-
ok@cs.otago.ac.nz
-
Richard A. O'Keefe