【发布时间】:2016-12-30 05:45:54
【问题描述】:
考虑一下(所有命令都在 64 位 Arch Linux 系统上运行):
-
Perl (v5.24.0)
$ perl -le 'print 10190150730169267102/1000%10' 6 -
awk(GNU awk 4.1.3)$ awk 'BEGIN{print 10190150730169267102/1000%10}' 6 -
R (3.3.1)
> (10190150730169267102/1000)%%10 [1] 6 -
bc$ echo 10190150730169267102/1000%10 | bc 7 -
Python 2 (2.7.12)
>>> print(10190150730169267102/1000%10) 7 -
Python 3 (3.5.2)
>>> print(10190150730169267102/1000%10) 8.0
所以,Perl、gawk 和 R 同意,bc 和 Pyhon 2 也同意。不过,在测试的 6 个工具之间,我得到了 4 个不同的结果。我知道这与四舍五入的整数长度有关,但为什么不同的工具差异如此之大?我曾预计这将取决于处理器处理大量数字的能力,但它似乎取决于语言的内部特性(或错误)。
有人能解释一下幕后发生的事情吗?每种语言的限制是什么?为什么它们的行为如此不同?
【问题讨论】:
-
Perl、awk 和 R 似乎转换为双精度浮点数进行除法,最接近
double的10190150730169267102是10190150730169266176,这解释了6。 -
Re "为什么会有这么大的差异",原来的数字相差了0.0000000000000001。几乎没有巨大!那是 16 位精度!
-
@terdon - 不,使用
-Mbigint而不是-MMath::BigInt,你会得到 7。你所做的只会加载 M::BI 模块,但不会将所有数字转换为 M ::BI 对象默认情况下,只有bigint这样做。 -
@terdon,不,第 17 位有效数字的差异与“相当重要”完全相反。
-
@terdon,没关系。您应该吸取的教训是双精度数字不适合您的解决方案。
标签: python perl awk rounding long-integer