Целочисленное деление в awk
Я хочу разделить два числа в awk
, используя целочисленное деление, т.е. обрезая результат. Например
k = 3 / 2
print k
должен печатать 1
В соответствии с руководство,
Отдел; поскольку все числа в awk являются числами с плавающей запятой, результат не округляется до целого числа
Есть ли какое-либо обходное решение для получения целочисленного значения?
Причина в том, что я хочу получить средний элемент массива с целыми индексами [0 - num-1].
Ответы
Ответ 1
Используйте функцию int
, чтобы получить целую часть результата, усеченную в направлении 0. Это приводит к получению ближайшего целого числа к результату, расположенному между результатом и 0. Например, int(3/2)
равно 1, int(-3/2)
-1.
Источник: Руководство AWK - числовые функции
Ответ 2
Безопасное и быстрое целочисленное деление awk можно выполнить с помощью:
q=(n-n%d)/d+(n<0)
Ответ 3
В простых случаях вы можете безопасно использовать int()
, который усекает в нуль 1:
awk 'BEGIN { print int(3 / 2) }' # prints 1
gawk 'BEGIN { print int(-3 / 2) }' # prints -1; not guaranteed in POSIX awk
Имейте в виду, что awk всегда использует числа с плавающей запятой с двойной точностью 2 и арифметику с плавающей запятой 3. Единственный способ получить целые числа и целочисленную арифметику - использовать внешние инструменты, например. стандартная утилита expr
:
awk 'BEGIN { "expr 3 / 2" | getline result; print result; }' # prints 1
Это действительно неудобно, долго, медленно, но безопасно и портативно.
1 В POSIX awk, усечение до нуля гарантируется только для положительных аргументов: int (x) - Возвращает аргумент, усеченный до целого. Усечение должно быть равным 0 при х > 0. GNU awk (gawk) использует усечение к нулю даже для отрицательных чисел: int (x) - возвращает ближайшего целого числа к x, расположенного между x и нулем и усеченного к нулю. Например, int (3) равно 3, int (3.9) равно 3, int (-3.9) - -3, а int (-3) также равно 3.
2 Числовые выражения задаются как float с двойной точностью в Выражения в awk в POSIX.
3 Вся арифметика должна следовать семантике арифметики с плавающей запятой, указанной в стандарте ISO C (см. Концепции, полученные из стандарта ISO C). - POSIX awk: Арифметические функции
Если вы решите использовать поплавки, вы должны знать об их причудах и быть готовыми обнаружить их и избежать связанных ошибок. Несколько страшных примеров:
-
Непредставимые числа:
awk 'BEGIN { x = 0.875; y = 0.425; printf("%0.17g, %0.17g\n", x, y) }'
# prints 0.875, 0.42499999999999999
-
Скопления округления:
awk 'BEGIN{s=0; for(i=1;i<=100000;i++)s+=0.3; printf("%.10f, %d\n",s,int(s))}'
# prints 29999.9999999506, 29999
-
Ошибки с ошибками округления:
awk 'BEGIN { print (0.1 + 12.2 == 12.3) }' # prints 0
-
Точность уменьшается с увеличением, вызывая бесконечные петли:
awk 'BEGIN { for (i=10^16; i<10^16+5; i++) printf("%d\n", i) }'
# prints 10000000000000000 infinitely many times
Подробнее о том, как работают float: