Нечетная фильтрация очень маленьких чисел с плавающей запятой

#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 флага.