4

I recently found that for some very small values, filtering using AWK doesn't seem to behave correctly. As in the following file 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

I want to filter by the third column, below some threshold. For instance:

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

yields

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

notably omitting the second to last entry, 19:45431453 with the very small column 3 value 3.952525e-323.

However, when I threshold lower, at say 5e-5:

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

It picks it right up.

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

Any thoughts as to why and how I might get around this?

5
  • Type conversion rules? (Who gets converted, the string $3 or the number 0.5?) Try awk '($3 + 0.0 < 0.5) {print $3}' to make explicit that the left argument of < is a number.
    – AlexP
    Commented Dec 7, 2019 at 0:21
  • If you're using GNU awk (gawk) you could also try adding the -M (--bignum) option, to enable GMP support Commented Dec 7, 2019 at 0:43
  • 1
    Works fine in GNU Awk 5.0.1, even without -M. Which version are you using?
    – bu5hman
    Commented Dec 7, 2019 at 9:29
  • @bu5hman my system is on awk 4.0.2, so that may be it.
    – Aomdahl
    Commented Dec 7, 2019 at 18:49
  • @AlexP that worked like a charm! Thank you. I guess I need to take a closer look at awk type conversion rules.
    – Aomdahl
    Commented Dec 7, 2019 at 18:50

1 Answer 1

3

This issue can be reproduced on awk instances without MPFR or MP support for multiple precision. There is a limitation ~ e-308 and e+308 for very big or very small numbers.

See Table 16.1 here: https://www.gnu.org/software/gawk/manual/gawk.html#Computer-Arithmetic

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

You can find out if your awk supports multiple-precision from the output of awk --version (see above link). Also -M option will not work if only double precision is supported.


For example, for GNU Awk 4.2.1, API: 2.0 without MPFR I run this example (not reproducible with 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

Note that $0+0 evaluates to zero in case $0 is a string that doesn't represent a valid number. Also any comparison like $0>0 will be a string, not numeric, comparison for these cases.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .