Perl5 formline 向下舍入精确值 0.5 不向上舍入
Perl5 formline round down the exact value 0.5 not round up
我注意到 Perl 5 中的 formline 方法有一些奇怪的动作。
如果十进制值大于 0.5,则向上舍入。
如果小数值小于 0.5,则向下舍入。
但是当十进制值精确到 0.5 时,我们通常应该四舍五入,但 formline 将值四舍五入。
有谁知道这是错误还是预先设计好的?谢谢。
在没有具体演示的情况下,我将指出两个可能的罪魁祸首:
"We normally should round up" 绝对是错误的。有许多不同的舍入系统。 sprintf
,例如,使用四舍五入。
$ perl -E'say sprintf "%1$.1f => %1$.0f", $_ for 3.5, 4.5, 5.5, 6.5'
3.5 => 4
4.5 => 4
5.5 => 6
6.5 => 6
你认为有5/10小数部分的数字实际上不是浮点精度误差。
很多数在二进制中都是周期性的,而周期性的数不能准确地存储为浮点数。例如,1/10、2/10、3/10、4/10、6/10、7/10、8/10 和 9/10 在二进制中都是周期性的,就像 1/3 在十进制中是周期性的(和二进制)。
5/10作为浮点数其实很容易存储(5/10 = 1/2 = 2-1),但是如果你通过算术得到这个数,您实际上可能没有 5/10。
$ perl -E'$x += 0.01 for 1..50; say sprintf "%.40f", $x'
0.5000000000000002220446049250313080847263
我注意到 Perl 5 中的 formline 方法有一些奇怪的动作。 如果十进制值大于 0.5,则向上舍入。 如果小数值小于 0.5,则向下舍入。 但是当十进制值精确到 0.5 时,我们通常应该四舍五入,但 formline 将值四舍五入。
有谁知道这是错误还是预先设计好的?谢谢。
在没有具体演示的情况下,我将指出两个可能的罪魁祸首:
"We normally should round up" 绝对是错误的。有许多不同的舍入系统。
sprintf
,例如,使用四舍五入。$ perl -E'say sprintf "%1$.1f => %1$.0f", $_ for 3.5, 4.5, 5.5, 6.5' 3.5 => 4 4.5 => 4 5.5 => 6 6.5 => 6
你认为有5/10小数部分的数字实际上不是浮点精度误差。
很多数在二进制中都是周期性的,而周期性的数不能准确地存储为浮点数。例如,1/10、2/10、3/10、4/10、6/10、7/10、8/10 和 9/10 在二进制中都是周期性的,就像 1/3 在十进制中是周期性的(和二进制)。
5/10作为浮点数其实很容易存储(5/10 = 1/2 = 2-1),但是如果你通过算术得到这个数,您实际上可能没有 5/10。
$ perl -E'$x += 0.01 for 1..50; say sprintf "%.40f", $x' 0.5000000000000002220446049250313080847263