Per PDL::Math's rint
documentation, rint
uses "round half to even" (aka "banker's rounding"). They then go on to explain that to always round half up (regardless of sign, so 4.5 to 5.0 and -4.5 to -4.0), use floor($x+0.5)
, and to round half away from zero (so 4.5 to 5.0 and -4.5 to -5.0), use ceil(abs($x)+0.5)*($x<=>0)
I ran the following in the perldl
shell, adding some extra example numbers:
pdl> p $pdl = pdl [5.55, 45, 55, -45, -55, 4.45, 4.55, -4.45, -4.55]
[5.55 45 55 -45 -55 4.45 4.55 -4.45 -4.55]
pdl> p $n = pdl [.3, 10, 10, 10, 10, .1, .1, .1, .1]
[0.3 10 10 10 10 0.1 0.1 0.1 0.1]
pdl> p "bankers rounding: " => rint($pdl/$n)*$n
bankers rounding: [5.4 40 60 -40 -60 4.4 4.5 -4.4 -4.5]
pdl> p "round half up: " => floor($pdl/$n+0.5)*$n
round half up: [5.7 50 60 -40 -50 4.5 4.5 -4.4 -4.5]
pdl> p "round half away: " => ceil(abs($pdl/$n)+0.5)*(($pdl/$n)<=>0)*$n
round half away: [5.7 50 60 -50 -60 4.5 4.6 -4.5 -4.6]
Aside: On your "correct" output, I don't see how 5.55 rounded by 0.3 should be 5.6, as 5.6 is not a multiple of 0.3. The nearest multiple of 0.3 above 5.55 is 5.7.
Update: Looking at Math::Round::nearest(), it looks like it rounds toward infinity, so the "round half away" example would be what matches the behavior of "equivalent to Math::Round::nearest()"