从前有一位聪明的仆人,他救下了一位王子的性命。 国王答应,仆人想要什么,就赏他什么。 仆人知道国王喜欢下国际象棋,便告诉国王,他想要麦粒。 棋盘的第一格放一粒麦粒,之后每一格的数量都翻一倍。
计算棋盘上的小麦粒数。
棋盘有 64 个格子。 第 1 格有 1 粒小麦,第 2 格有 2 粒,第 3 格有 4 粒,以此类推,每格数量翻倍。
编写代码来计算:
默认情况下,awk中的数字以双精度浮点数表示。这能提供 53 位的精度(参见手册中的表 16.3)。遗憾的是,这不足以完成本练习(剧透一下,有一个测试需要 63 位的精度)。
“精度不足”看起来是这样的:
$ gawk 'BEGIN {
n = 2 ^ 54
if (n == n + 1)
print "not enough precision"
else
print "OK"
}'
not enough precision
如果相关库已经编译进awk可执行文件,GNU awk就能使用任意精度的数字。检查一下你的 awk 版本,看看有没有 “GNU MPFR”:
$ gawk --version
GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)
...
如果存在,就用-M选项启用这项功能:
$ gawk -M 'BEGIN {
n = 2 ^ 54
if (n == n + 1)
print "not enough precision"
else
print "OK"
}'
OK
如果我的awk没有-M怎么办?那就得调用一个能做任意精度算术的外部程序,比如bc。具体做法参见从管道使用 getline 读入变量一节。
延伸阅读:任意精度算术