awk 过滤科学记数法数字的行为不一致

awk 过滤科学记数法数字的行为不一致

我最近发现,对于一些非常小的值,使用 AWK 进行过滤似乎表现不正确。如以下文件所示test_loc.txt

10:10000018 10  0.4505
X:99997421  X   0.95508
X:99997626  X   0.016206
X:99998439  X   0.5043
10:100001724    10  0.69838
10:100001867    10  0.48936
2:137078930 2   2.8245e-05
10:100001868    10  0.11326
10:100002378    10  0.6674
19:45431453 19  3.952525e-323
10:100002464    10  0.87964

我想按低于某个阈值的第三列进行过滤。例如:

awk '($3 < 0.5) {print $0}' test_loc.txt

产量

10:10000018 10  0.4505
X:99997626  X   0.016206
10:100001867    10  0.48936
2:137078930 2   2.8245e-05
10:100001868    10  0.11326

特别是省略了倒数第二个条目,19:45431453其中第 3 列值非常小3.952525e-323

然而,当我的阈值降低时,例如5e-5

awk '($3 < 5e-5) {print $0}' test_loc.txt

它立即将其拾起。

2:137078930 2   2.8245e-05
19:45431453 19  3.952525e-323

关于为什么以及如何解决这个问题有什么想法吗?

答案1

awk在没有 MPFR 或 MP 支持多精度的实例上可能会重现此问题。e-308对于e+308非常大或非常小的数字有一个限制。

请参阅此处的表 16.1:https://www.gnu.org/software/gawk/manual/gawk.html#计算机算术

也可以看看:https://www.gnu.org/software/gawk/manual/html_node/MPFR-features.html

您可以从(参见上面的链接)awk的输出中了解您是否支持多精度。如果仅支持双精度,该选项awk --version-M将不起作用。


例如,对于GNU Awk 4.2.1, API: 2.0没有 MPFR 的情况,我运行此示例(无法使用 awk 5 重现)

$ cat file
1e-305
1e-306
1e-307
1e-308
1e-309
1e-310
$ awk '$0+0 > 0' file
1e-305
1e-306
1e-307

请注意,如果字符串不代表有效数字,$0+0则计算结果为零。对于这些情况$0,任何比较都$0>0将是字符串比较,而不是数字比较。

相关内容