According to the GNU awk manual,

The way printf and sprintf() (see Printf) perform rounding often depends upon the system's C sprintf() subroutine. **On many machines, sprintf() rounding is “unbiased,”** which means it doesn't always round a trailing ‘.5’ up, contrary to naive expectations. **In unbiased rounding, ‘.5’ rounds to even,** rather than always up, so 1.5 rounds to 2 but 4.5 rounds to 4.

The same page also has an example `round()`

function:

```
function round(x, ival, aval, fraction)
{
ival = int(x) # integer part, int() truncates
# see if fractional part
if (ival == x) # no fraction
return ival # ensure no decimals
if (x < 0) {
aval = -x # absolute value
ival = int(aval)
fraction = aval - ival
if (fraction >= .5)
return int(x) - 1 # -2.5 --> -3
else
return int(x) # -2.3 --> -2
} else {
fraction = x - ival
if (fraction >= .5)
return ival + 1
else
return ival
}
}
```