我有这个表格。
a 0
b 0
c 1.6149e-315
d 5.2587e-265
e 8.2045e-227
f 8.2045e-227
如果我输入
$awk '($2<1){print}' my_file.txt
它返回
a 0
b 0
d 5.2587e-265
e 8.2045e-227
f 8.2045e-227
但它认为第三行的值1.6149e-315大于1。
$awk '($2>1){print}' my_file.txt
c 1.6149e-315
这种行为的原因是什么?是不是负指数<1e-300太小了,所以它去掉了 "e-"部分?看起来是这样,因为
$awk '($2>1.6149){print}' my_file.txt
c 1.6149e-315
但如果我跑
$ awk '($2>1.615){print}' my_file.txt
什么都没有输出。
我如何克服这个问题?
像这样运行你的awk。
awk '($2+0) < 1' file
这将输出:
a 0
b 0
c 1.6149e-315
d 5.2587e-265
e 8.2045e-227
f 8.2045e-227
$2+0
转换 $2
变成一个数字值。
另外在 GNU Awk 5.0.1
即使没有这个技巧,我也能得到正确的输出。
转载OP的问题与 GNU Awk 4.2.1
.
$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 '$2+0>0' file
d 5.2587e-265
e 8.2045e-227
f 8.2045e-227
样本输入的第三个数字没有再被打印出来,而它应该大于零。
而这里我们看到第三个数字只有零。
awk '{printf "%.320f\n",$2+0}' file
以上都说明 e^-315
没有以预期的方式表示。
看起来你已经超过了极限,那就是...。-308
为双精度浮点。左右 e^-308
是要表示的最小正非零值。
https:/www.gnu.orgsoftwaregawkmanualgawk.html#Computer-Arithmetic
此外,如果你的gnu awk编译时支持MPFR,你可以使用-M选项拥有多个精度的数字,这似乎是表示一个正数的唯一方式,小于 10^-308
https:/www.gnu.orgsoftwaregawkmanualhtml_nodeMPFR-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 '$2+0>0' file
f 1.1e-307
g 1.1e-306
h 1.1e-305
指数小于 -308
是不按预期处理的。
> awk '{print($2+0)}' file
0
0
0
0
0
1.1e-307
1.1e-306
1.1e-305
这就是证明,即 $NF+0
力为零,而不是指数数,任何超出的数字都是 ^-308
不能表示,因为该限制存在于双精度的awk实例中,不支持多精度。