Reputation: 297
I am trying to sum a list of integers from a logfile using awk
{sum+=$1} END {print sum}
The problem is that the result is larger than the MAX_INT specified in my limits.h file, so the print returns 3.68147e+09
Is there an elegant way of printing the entire value of the sum?
Thank you!
Upvotes: 6
Views: 6194
Reputation: 195179
gnu awk has -M
option, you can try with it. it should keep the precision for you.
The MPFR and MP libraries
should be used when you compile gawk, not at run time.
here is an example, with or without -M
. tested with gawk 4.1.0
on 64bit linux (Archlinux):
kent$ awk 'BEGIN{printf "%d\n","368147000099999999999999999999999999"}'
368147000099999983291776543710248960
kent$ awk -M 'BEGIN{printf "%d\n","368147000099999999999999999999999999"}'
368147000099999999999999999999999999
Upvotes: 5
Reputation: 123608
You could use bc
which supports arbitrary precision arithmetic. The equivalent of what you're trying to achieve would be:
cut -d' ' -f1 inputfile | paste -sd+ | bc -l
EDIT: As per your comment, if you want to prevent splitting of output into multiple lines, set BC_LINE_LENGTH
to 0
. Say:
cut -d' ' -f1 inputfile | paste -sd+ | BC_LINE_LENGTH=0 bc -l
Upvotes: 1
Reputation: 3931
I'm pretty sure that AWK uses double, internally, for arithmetic, so beyond a certain limit, you're going to loose precision.
Have a look on this link if it helps you out.
Adding large number using AWK issue cases
Upvotes: 0
Reputation: 198436
awk
does not have integral type that is large enough for your data, and promotes the sum into floating point. As far as I know, there is no data type in awk
with enough precision for what you ask. I.e. the problem is not in printing; awk literally does not have the information you want.
You can try ruby
instead, for example (it promotes integers into big integers rather than into floats):
ruby -nae 'BEGIN{sum=0}; END{puts sum}; sum+=$F[0].to_i'
Upvotes: 3