为什么4种不同的语言会给出4种不同的结果?

ter*_*don 5 python perl awk rounding long-integer

考虑一下(所有命令都在64位Arch Linux系统上运行):

所以,Perl,gawkR同意,bc和Pyhon 2.然而,在测试的6个工具之间,我得到了4个不同的结果.我知道这与整数很长的整数有关,但为什么不同的工具差别如此之大?我曾预料到这将取决于处理器处理大数字的能力,但它似乎取决于语言的内部特征(或错误).

有人可以解释幕后发生的事情吗?每种语言有哪些限制,为什么它们的表现如此不同?

Mar*_*son 9

您看到不同的结果有两个原因:

  1. 除法步骤是做两件事:在你尝试的一些语言中,它表示整数除法,它丢弃结果的小数部分,只保留整数部分.在其他情况下,它代表实际的数学划分(遵循Python的术语,我将在下面称为"真正的划分"),返回接近真实商的浮点结果.

  2. 在某些语言(支持任意精度的语言)中,10190150730169267102正好表示大的分子值; 在其他情况下,它被最近的可表示浮点值替换.

上面1.和2.中可能性的不同组合给出了不同的结果.

详细说明:在Perl,awk和R中,我们正在使用浮点值和真正的除法.该值10190150730169267102太大而无法存储在机器整数中,因此它以通常的IEEE 754 binary64浮点格式存储.该格式不能代表该特定值完全,所以什么都存储是最接近的值在格式,这是表示的10190150730169266176.0.现在我们将该近似值除以1000,再次给出一个浮点结果.精确的商,10190150730169266.176再次不能完全表示为binary64格式,我们得到最接近的可表示的浮点数,恰好是10190150730169266.0.取余数模数10给出6.

在bc和Python 2中,我们使用任意精度整数和整数除法.这两种语言都可以完全代表分子.然后是除法结果10190150730169267(我们正在进行整数除法,而不是真正的除法,因此丢弃小数部分),其余模数107.(这有点过于简单化了:bc在内部使用的格式Decimal比Python的类型更接近于任意精度整数类型,但在这种情况下效果是相同的.)

在Python 3中,我们使用任意精度整数和真正的除法.分子的确切表示,但除法的结果是与真商最接近的浮点值.在这种情况下,精确的商是10190150730169267.102,并且最接近的可表示的浮点值是10190150730169268.0.取该值模的剩余部分10给予8.

摘要:

  • Perl,awk,R:浮点近似,真正的除法
  • bc,Python 2:任意精度整数,整数除法
  • Python 3:任意精度整数,真正的除法