Integer division in awk
Use the int
function to get the integer part of the result, truncated toward 0. This produces the nearest integer to the result, located between the result and 0. For example, int(3/2)
is 1, int(-3/2)
is -1.
Source: The AWK Manual - Numeric Functions
In simple cases, you can safely use int()
which truncates towards zero1:
awk 'BEGIN { print int(3 / 2) }' # prints 1
gawk 'BEGIN { print int(-3 / 2) }' # prints -1; not guaranteed in POSIX awk
Keep in mind that awk always uses double-precision floating point numbers2 and floating-point arithmetic3, though. The only way you can get integers and integer arithmetic is to use external tools, e.g. the standard expr
utility:
awk 'BEGIN { "expr 3 / 2" | getline result; print result; }' # prints 1
This is really awkward, long, slow, … but safe and portable.
1 In POSIX awk, truncation to zero is guaranteed only for positive arguments: int(x) — Return the argument truncated to an integer. Truncation shall be toward 0 when x>0. GNU awk (gawk) uses truncation toward zero even for negative numbers: int(x) — Return the nearest integer to x, located between x and zero and truncated toward zero. For example, int(3) is 3, int(3.9) is 3, int(-3.9) is -3, and int(-3) is -3 as well.
2 Numeric expressions are specified as double-precision floats in Expressions in awk in POSIX.
3All arithmetic shall follow the semantics of floating-point arithmetic as specified by the ISO C standard (see Concepts Derived from the ISO C Standard). — POSIX awk: Arithmetic functions
If you choose to use floats, you should know about their quirks and be ready to spot them and avoid related bugs. Several scary examples:
Unrepresentable numbers:
awk 'BEGIN { x = 0.875; y = 0.425; printf("%0.17g, %0.17g\n", x, y) }' # prints 0.875, 0.42499999999999999
Round-off errors accumulation:
awk 'BEGIN{s=0; for(i=1;i<=100000;i++)s+=0.3; printf("%.10f, %d\n",s,int(s))}' # prints 29999.9999999506, 29999
Round-off errors ruin comparisons:
awk 'BEGIN { print (0.1 + 12.2 == 12.3) }' # prints 0
Precision decreases with magnitude, causing infinite loops:
awk 'BEGIN { for (i=10^16; i<10^16+5; i++) printf("%d\n", i) }' # prints 10000000000000000 infinitely many times
Read more on how floats work:
Stack Overflow tags floating-point wiki
Wikipedia article Floating point
GNU awk arbitrary precision arithmetic – contains both info on the specific implementation and general knowledge
Safe and quick awk integer division can be done with:
q=(n-n%d)/d+(n<0)