awk 算术不同于 expr

1 awk arithmetic expr

awk 算法和 expr 之间有一些对比输出。

例子

expr 11111111111111111111 / 22
Run Code Online (Sandbox Code Playgroud)

505050505050505050
Run Code Online (Sandbox Code Playgroud)

但是使用 awk:

echo '11111111111111111111' | awk '{q=$1/22;;print q}'
Run Code Online (Sandbox Code Playgroud)

505050505050505024
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下吗?

ilk*_*chu 6

大概你awk使用浮点值的作品,就像 GNU awk 似乎做的:

$ gawk 'BEGIN{ a = 11111111111111111111; print a, a/22; }'
11111111111111110656 505050505050505024
Run Code Online (Sandbox Code Playgroud)

它不能11111111111111111111准确存储,也不能准确存储余数(11111111111111111111 / 22is 505050505050505029.81...)。

您的expr数字范围似乎更广。我的没有(来自 GNU coreutils 8.26 的那个):

$ expr 11111111111111111111 / 22
expr: 11111111111111111111: Numerical result out of range
Run Code Online (Sandbox Code Playgroud)

正如@steeldriver评论的那样,当前版本的GNU awk 还能够使用GNU MPFR 库进行高精度算术。例如,四精度浮点数足以给出这个除法的准确答案:

$ gawk -M -v PREC="quad" -v OFMT="%.6f" \
  'BEGIN{ a = 11111111111111111111; print a, a/22; }'
11111111111111111111 505050505050505050.500000
Run Code Online (Sandbox Code Playgroud)

除此之外,bc或者 Python 可以用于任意大的数字。

  • 请注意,至少较新版本的 GNU awk 具有 [获得所需的准确性](https://www.gnu.org/software/gawk/manual/gawk.html#Getting-Accuracy) 的功能,例如 `gawk -M - v PREC="quad" -v OFMT="%.0f" 'BEGIN{ a = 11111111111111111111; 打印 a, a/22; }'` (3认同)