Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange "half to even" rounding in different languages [closed]

GNU bash, version 4.2.24:

$> printf "%.0f, %.0f\n" 48.5 49.5
48, 50

Ruby 1.8.7

> printf( "%.0f, %.0f\n", 48.5, 49.5 )
48, 50

Perl 5.12.4

$> perl -e 'printf( "%.0f, %.0f\n", 48.5, 49.5 )'
48, 50

gcc 4.5.3:

> printf( "%.0f, %.0f\n", 48.5, 49.5 );
48, 50

GHC, version 7.0.4:

> printf "%.0f, %.0f\n" 48.5 49.5
49, 50

Wikipedia says that this kind of rounding is called round half to even:

This is the default rounding mode used in IEEE 754 computing functions and operators.

Why is this rounding used by default in C, Perl, Ruby and bash, but not in Haskell?

Is it some sort of tradition or standard? And if it is a standard, why it's used by those languages and not used by Haskell? What is a point of rounding half to even?

like image 901
ДМИТРИЙ МАЛИКОВ Avatar asked Mar 22 '12 20:03

ДМИТРИЙ МАЛИКОВ


3 Answers

GHCi> round 48.5
48
GHCi> round 49.5
50

The only difference is that printf isn't using round — presumably because it has to be able to round to more than just whole integers. I don't think IEEE 754 specifies anything about how to implement printf-style formatting functions, just rounding, which Haskell does correctly.

It would probably be best if printf was consistent with round and other languages' implementations, but I don't think it's really a big deal.

like image 183
ehird Avatar answered Nov 07 '22 23:11

ehird


"Round to even" is the default for use with IEEE 754. Haskell should probably switch to using it in printf for consistency reasons. The relevant line of code is in GHC.Float

f 0 (x:_)  = (if x >= b2 then 1 else 0, [])

So, if someone wants to fix it, they can. As ehird points out, this would just make the roundTo function being used by printf consistent with round although I'm not sure what other code this change would break.

EDIT: a previous version of this answer got the location of the rounding code wrong. The only significant difference between the two implementations is if they are hardcoded to use base 10.

like image 44
Philip JF Avatar answered Nov 07 '22 21:11

Philip JF


I can't say for sure, but this probably has to do with the fact that this type of rounding is commonly used in accounting functions, as this is also known as Banker's rounding. If you look further at the Wikipedia article on rounding, you'll also notice this is default in IEEE 754, so likely Haskell isn't following that standard.

like image 2
Tom A Avatar answered Nov 07 '22 22:11

Tom A