awk:负指数没有被正确解释

awk: negative exponential is not correctly interpreted

我有这个table:

a   0
b   0
c   1.6149e-315
d   5.2587e-265
e   8.2045e-227
f   8.2045e-227

如果我输入

$awk '(<1){print}' my_file.txt

它returns

a   0
b   0
d   5.2587e-265
e   8.2045e-227
f   8.2045e-227

但它认为第三行中的值 1.6149e-315 大于 1:

$awk '(>1){print}' my_file.txt 
c   1.6149e-315

这种行为的原因是什么?负指数 <1e-300 是否太小,所以它删除了 "e-" 部分?看起来是这样,因为

$awk '(>1.6149){print}' my_file.txt 
c   1.6149e-315

但是如果我运行

$ awk '(>1.615){print}' my_file.txt

没有输出。

我该如何克服这个问题?

运行 你的 awk 是这样的:

awk '(+0) < 1' file

这将输出:

a   0
b   0
c   1.6149e-315
d   5.2587e-265
e   8.2045e-227
f   8.2045e-227

+0</code> 转换为数值。</p> <p>顺便说一下 <code>GNU Awk 5.0.1,即使没有这个技巧我也能得到正确的输出。

GNU Awk 4.2.1 重现了 OP 的问题。


首先,$NF+0 似乎没有解决这个问题,正如我们在这个例子中看到的那样:

> cat file
a   0
b   0
c   1.6149e-315
d   5.2587e-265
e   8.2045e-227
f   8.2045e-227

> awk '+0>0' file
d   5.2587e-265
e   8.2045e-227
f   8.2045e-227

示例输入的第三个数字不会再次打印,而它应该大于零。

这里我们只看到第三个数字为零。

awk '{printf "%.320f\n",+0}' file

以上表示 e^-315 没有以预期的方式表示。


您似乎已经超出了双精度浮点数的限制 -308e^-308左右是要表示的最小正非零值。

https://www.gnu.org/software/gawk/manual/gawk.html#Computer-Arithmetic


此外,如果您的 gnu awk 是在支持 MPFR 的情况下编译的,您可以使用 -M 选项获得多个精度数字,这似乎是表示小于 10^-308[=25 的正数的唯一方法=]

https://www.gnu.org/software/gawk/manual/html_node/MPFR-features.html


最后一个参数,一个简单的测试:

> cat file
a   1.1e-312
b   1.1e-311
c   1.1e-310
d   1.1e-309
e   1.1e-308
f   1.1e-307
g   1.1e-306
h   1.1e-305
> awk '+0>0' file
f   1.1e-307
g   1.1e-306
h   1.1e-305

小于 -308 的指数未按预期处理。

> awk '{print(+0)}' file
0
0
0
0
0
1.1e-307
1.1e-306
1.1e-305

这是证明,$NF+0 强制为零而不是指数数,任何超过 ^-308 的数字都不能表示,因为该限制存在于具有双精度的 awk 实例-精度,不支持多精度。