Rounding decimal numbers in perl, wrong result

被刻印的时光 ゝ 提交于 2019-11-30 16:03:06
Orbling

floor() is not for rounding, it goes down to the nearest integer.

See this old post: How do you round a floating point number in Perl?

The “correct” way to round is whatever way you choose to define as correct for whatever purpose you have in mind. People have thought a lot about it, and some strategies are more appropriate for some application areas than they are in others.

Rounding toward zero by using int() is seldom what people want. Usually they want something that is numerically unbiased.

Fair splits the fives; hence the shorthand term, “round towards even”. The nearer integer isn’t defined: there is no nearer integer when the least siginficant digit is 5. There are 9 things that when rounded give a different answer: 1,2,3,4,5,6,7,8,9.

To be fair, you must have half of those go one way and half go the other. But there are nine numbers, so you have four go one way and four go the other, but now you have a fairness problem. The only way therefore to avoid bias is for the 5 cases to alternate up and down. That’s why it works this way.

% perl -e 'printf "%.0f\n", $_+.5 for -10 .. +10'

produces the sequence

-10 -8 -8 -6 -6 -4 -4 -2 -2 -0 0 2 2 4 4 6 6 8 8 10 10

While this round-towards-zero approach:

% perl -e 'print int($_+.5)," " for -10 .. +10; print "\n"'

makes this with a hump in the middle:

 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 0 1 2 3 4 5 6 7 8 9 10 

Looking again at round-towards-even:

% perl -le 'printf "%.1f ", $_+.05 for -10 .. +10'

-9.9 -8.9 -8.0 -7.0 -6.0 -5.0 -4.0 -3.0 -1.9 -0.9 0.1 1.1 2.0 3.0 4.0 5.0 6.0 7.0 8.1 9.1 10.1 

That makes more sense if you do this:

% perl -le 'printf "%.2f ", $_+.05 for -10 .. +10'

-9.95 -8.95 -7.95 -6.95 -5.95 -4.95 -3.95 -2.95 -1.95 -0.95 0.05 1.05 2.05 3.05 4.05 5.05 6.05 7.05 8.05 9.05 10.05 

and then consider what towards even means.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!