#awk #floating-point
#awk #с плавающей запятой
Вопрос:
gawk
отфильтровывает очень маленькое положительное число по-разному в зависимости от используемого порога, но все пороговые значения должны сохранять запись.
Пример входного файла, tmp
:
A 3.92e-373
B 5e-300
C 5e-20
D 5e-6
E 5e-3
Вывод:
% gawk '$2 < 5e-4' tmp
B 5e-300
C 5e-20
D 5e-6
% gawk '$2 < 5e-8' tmp
A 3.92e-373
D 5e-300
C 5e-20
Примечание gawk '$2 < 5e-4'
должно сохранять запись как $2 < 3.92e-373
, которая работает для gawk '$2 < 5e-8'
.
Очевидно, что это проблема с ограничением числа с плавающей запятой, но я нахожу странным, что результат не согласуется для обоих пороговых значений. Не следует ли gawk
просто ограничить 3.92e-373
0
и, таким образом, напечатать эту строку при любых обстоятельствах?
Ответ №1:
Я бы не стал предполагать, что gawk может определить, какое число соответствует строке, учитывая ваши входные и жестко заданные значения. Убедитесь, что они обрабатываются как числа, используя strtonum()
для них:
$ gawk 'strtonum($2) < strtonum("5e-4")' file
A 3.92e-373
B 5e-300
C 5e-20
D 5e-6
$ gawk 'strtonum($2) < strtonum("5e-8")' file
A 3.92e-373
B 5e-300
C 5e-20
Вы можете увидеть, с какими типами, по мнению gawk, он имеет дело, вызывая typeof() для каждого:
$ gawk '{print typeof($2), $2, typeof(5e-4), 5e-4, strtonum($2), strtonum("5e-4")}' file | column -t
string 3.92e-373 number 0.0005 0 0.0005
strnum 5e-300 number 0.0005 5e-300 0.0005
strnum 5e-20 number 0.0005 5e-20 0.0005
strnum 5e-6 number 0.0005 5e-06 0.0005
strnum 5e-3 number 0.0005 0.005 0.0005
Похоже strtonum("5e-4")
, что это избыточно, но ИМХО это улучшает ясность, поэтому я бы оставил это.
Обратите внимание, что gawk не распознает автоматически 3.92e-373
как число, и поэтому сравнение для этого ввода будет строкой против числа, и это выполняется как сравнение строк (см. Таблицу по адресу https://www.gnu.org/software/gawk/manual/gawk.html#Typing-and-Comparison ).
Комментарии:
1. Спасибо за подробное объяснение, очень признателен. Это устранило мою проблему, и я узнал кое-что новое! Кроме того, другим решением, которое я нашел, было использование более поздней версии
gawk
с поддержкой произвольной точности с использованием-M
флага.