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
没有以预期的方式表示。
您似乎已经超出了双精度浮点数的限制 -308
。 e^-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 实例-精度,不支持多精度。
我有这个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
没有以预期的方式表示。
您似乎已经超出了双精度浮点数的限制 -308
。 e^-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 实例-精度,不支持多精度。