我正在研究用Perl编写的记帐脚本,我想知道执行十进制算术计算的“正确”方法是什么。例如,我想确保这样的比较正常工作:

"0.1" + "0.1" + "0.1" == "0.3"
"258.9" * "2000" == "517800"
...

在Python中,我将使用Decimal类型作为值,但是在Perl中我该怎么做?

最佳答案

(注意:有Math::Currency,但当前已损坏)。

使用 Math::BigFloat 将数字表示为任意精度对象。

use Math::BigFloat;

print Math::BigFloat->new(0.1) +
      Math::BigFloat->new(0.1) +
      Math::BigFloat->new(0.1) == Math::BigFloat->new(0.3);

您可以使用 bignum 自动执行此操作...
use bignum;

print 0.1 + 0.1 + 0.1 == 0.3;

但是! 魔术只对数字有效。如果您尝试将字符串添加在一起将无法正常工作,那么魔术来不及了。您必须明确地迫使它们成为数字。要对字符串进行数字化处理,您可以在字符串中添加0,例如$a += 0。或者,您可以通过以0 +开头来强制将方程式做为大数,它将沿线向下层叠。
use bignum;

$a = "0.1";
$b = "0.1";
$c = "0.1";
$d = "0.3";

# False
print $a + $b + $c == $d;

# True
print 0 + $a + $b + $c == $d;

两个警告。

首先,这一切都是以沉重的性能成本为代价的。不仅用于执行任意精度的数学运算,而且还用于所有方法和重载魔术。对它进行基准测试,看看是否可以接受。幸运的是,bignum仅升级其范围内的数字,而不升级整个程序。在bignum范围之外使用这些数字也是安全的,使用它们完成的所有数学运算也会被升级。

第二,Decimal将保留重要数字。 Math::BigFloat不会。

关于perl - 如何在Perl中执行小数运算?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34402394/

10-10 21:10
查看更多