当前 (g)awk 中的高整数在没有-M 的情况下奇怪地被破坏了。很容易发现BEGIN {print 2^1024} 产生inf,而BEGIN {print 2^1023} 有效。因此,人们会假设这个特定实现中的最大整数是 21024 − 1。但情况不是。
一个简单的实验,基于 21024 − 1 等于; 21023 +; 21022 +; ⋯ +; 21 +; 20:
BEGIN {for (i = 1023; i >= 0; --i) sum += 2^i; print sum}
这^^^产生无穷大,令人惊讶。那么,在什么时候我们需要停止添加 2 的幂才能获得有效的结果?在我的系统上,限制似乎是 971 — 尝试 970,它的总和为无穷大。
BEGIN {for (i = 1023; i >= 971; --i) sum += 2^i; print sum}
这个^^^ 打印179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368。
该值在awk 中有一个令人惊讶的属性:无论您添加什么,达到一定数量,都不会再改变它。 (尝试打印(例如)sum + 3。)增加它(尽管它似乎保持不变,基于print 输出)超过某个阈值最终会产生无穷大。这绝对是一个错误。
至于上面的原始总和 (21023 +; ⋯ + 2971),在awk 中仍然是正确的。一旦您尝试进一步增加该金额,事情就会开始崩溃。例如(并且令人惊讶),这仍然产生与上面相同的结果:
BEGIN {for (i = 1023; i >= 971; --i) sum += 2^i
for (i = 969; i >= 0; --i) sum += 2^i
print sum}
用 Python 检查两个总和很容易:
sum = 0
for i in range(971, 1024):
sum += 2**i
print(sum) # awk gets this right
for i in range(0, 970):
sum += 2**i
print(sum) # awk without -M gets this wrong
总而言之,我想从现在开始我会一直将-M 设置为awk!