It is as expected, it is "round to even", or "Banker's rounding".
A related site answer explain it.
The issue that such rule is trying to solve is that (for numbers with one decimal),
- x.1 up to x.4 are rounded down.
- x.6 up to x.9 are rounded up.
That's 4 down and 4 up.
To keep the rounding in balance, we need to round the x.5
- up one time and down the next.
That is done by the rule: « Round to nearest 'even number' ».
In code:
sh LC_NUMERIC=C printf '%.0f ' "$value"
awk echo "$value" | awk 'printf( "%s", $1)'
Options:
In total, there are four possible ways to round a number:
- The already explained Banker's rule.
- Round towards +infinite. Round up (for positive numbers)
- Round towards -infinite. Round down (for positive numbers)
- Round towards zero. Remove the decimals (either positive or negative).
Up
If you do need "round up (toward +infinite
)", then you can use awk:
value=195.5
awk echo "$value" | awk '{ printf("%d", $1 + 0.5) }'
bc echo "scale=0; ($value+0.5)/1" | bc
Down
If you do need "round down (Toward -infinite
)", then you can use:
value=195.5
awk echo "$value" | awk '{ printf("%d", $1 - 0.5) }'
bc echo "scale=0; ($value-0.5)/1" | bc
Trim decimals.
To remove the decimals (anything after the dot).
We could also directly use the shell (works on most shells - is POSIX):
value="127.54" ### Works also for negative numbers.
shell echo "${value%%.*}"
awk echo "$value"| awk '{printf ("%d",$0)}'
bc echo "scale=0; ($value)/1" | bc
To avoid the double-expansion problem (\u
is processed before %s
), you can use %b
, at least in Bash printf
:
printf '%b\n' \\u0024 \\u0025
You can pre-process your input in various ways:
set 0024 0025
printf '%b\n' "${@/#/\\u}"
The standalone printf
, as implemented in GNU coreutils, has the following restrictions on Unicode character specifications:
printf
interprets two character syntaxes introduced in ISO C 99: ‘\u
’ for 16-bit Unicode (ISO/IEC 10646) characters, specified as four hexadecimal digits hhhh, and ‘\U
’ for 32-bit Unicode characters, specified as eight hexadecimal digits hhhhhhhh. printf
outputs the Unicode characters according to the LC_CTYPE
locale. Unicode characters in the ranges U+0000…U+009F, U+D800…U+DFFF cannot be specified by this syntax, except for U+0024 ($), U+0040 (@), and U+0060 (`).
This explains why you can’t produce %
in this manner.
Best Answer
The
--
is used to tell the program that whatever follows should not be interpreted as a command line option toprintf
.Thus the
printf "--"
you tried basically ended up as "printf
with no arguments" and therefore failed.