최근에 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>0
숫자 비교가 아닌 문자열 비교가 됩니다.