Reputation: 41
I have a Linux bash script which is calculating the total of some values in a file using awk. I am using this syntax to do the calculations:
$ awk "BEGIN { print $first_number + $second_number }"
For calculations where the answer is a number below 9999.99, it displays the answer correctly. Above that value, it rounds the answer to one decimal place, or no decimal places, etc. like this:
$ awk "BEGIN { print 89.54 + 6789.44 }"
6878.98
$ awk "BEGIN {print 1.66 + 68790.77 }"
68792.4
$ awk "BEGIN {print 1.66 + 687990.77}"
687992
$ awk "BEGIN {print 10100.66 + 6787990.77}"
6.79809e+06
I want the answer to show the decimals, and to 2 decimal places in all instances.
DO you know why it is doing the unexpected roundings? Thanks
Upvotes: 4
Views: 1922
Reputation: 42149
As already answered by others, the problem is with the number formatting: use %.2f
with either printf
or AWK's OFMT
(that applies to print
) to get two decimal places.
To pass your shell variables to awk, you can use the -v
command-line option, e.g.,
$ awk -v a="$first_number" -v b="$second_number" 'BEGIN {
printf "%.2f\n", a + b
}'
If you always have exactly two decimal places, you could also use integer arithmetic in bash without the decimal point, and only format the output:
$ printf "%.2f\n" $(( 1010066 + 678799077 ))e-2
(Of course this only works for arithmetic operations that maintain the number of decimals, e.g., addition and subtraction.)
Upvotes: 1
Reputation: 85780
Expanding on top of James's useful answer, there is a reason why you see that behavior. It is because the exact manner in which numbers are converted into strings is controlled by a predefined variable in awk
called OFMT
when using print
OFMT's
default value is "%.6g"
, which creates a value with at most six significant digits. If you want print
to represent a more accurate representation, change it for e.g. to always represent 2 digits post the decimal point, something like "%2.2f"
$ awk 'BEGIN { OFMT = "%2.2f"; print 89.54 + 6789.44 }'
6878.98
$ awk 'BEGIN { OFMT = "%2.2f"; print 1.66 + 68790.77 }'
68792.4
$ awk 'BEGIN { OFMT = "%2.2f"; print 1.66 + 687990.77 }'
687992.43
$ awk 'BEGIN { OFMT = "%2.2f"; print 10100.66 + 6787990.77 }'
6798091.43
See here and here, which explains the behavior of these conversions.
Upvotes: 2
Reputation: 37424
Obviously print
is not the right tool to output decimals, use printf
and appropriate modifiers:
$ awk 'BEGIN {printf "%.2f\n", 10100.66 + 6787990.77}'
6798091.43
Also, use single quotes '
around the awk program.
Upvotes: 1