03/06/2019

# Awk Floating Point Number Addition Results Are Unexpected

I am using awk to grep ‘foo’ from a text file and cacluate sum of field # 7. But, result is rounded to an integer. I need exact result such as 385858.66 and not 385858 using the following command:

grep ‘foo’ 2012-2013.txt | awk ‘BEGIN{ sum=0.0}{ sub(“,”,””,\$7); sum +=\$7}END{ print “\$” sum}’
\$682444

I want \$682444.57 as output. How can I force “awk” to do floating point math?

Floating-point numbers or “real” numbers are that have a fractional part. awk uses double-precision floating-point numbers to represent all numeric values. In other words, all numbers in awk are floating-point numbers i.e. all calculation done using floating-point numbers.

## Example: Awk floating point calculation

The following example uses a file called trade.txt, which contains a list of week names as well as four profit values per week:

```week1 12.5 12.5 13.5 18.5
week2 11.5 11.10 12.10 13.70
week3 8.5  8.10 8.5 12.5
week4 9.5 11.5 13.5 16.5
week5 8	7 13 17
```

The following awk program takes the file trade.txt and prints the sum of all four values:

`awk '{ sum = \$2 + \$3 + \$4 + \$5; print \$1, sum }' trade.txt`

Sample outputs:

```week1 57
week2 48.4
week3 37.6
week4 51
week5 45```

The following awk program takes the file trade.txt and prints the average of all four values:

`awk '{ sum = \$2 + \$3 + \$4 + \$5; avg = sum/4; print \$1, sum , avg}' trade.txt`

Sample outputs:

```week1 57 14.25
week2 48.4 12.1
week3 37.6 9.4
week4 51 12.75
week5 45 11.25```

To avoid surprises use printf to format text to make your output more beautiful and meaningful:

`awk '{ sum = \$2 + \$3 + \$4 + \$5; avg = sum/4; printf "%s: \$%.2f (\$%05.2f)n",\$1, sum, avg}' trade.txt`

OR

`awk '{ sum = \$2 + \$3 + \$4 + \$5; avg = sum/4; printf "%s: \$%.2f (\$%5.2f)n",\$1, sum, avg}' trade.txt`

Sample outputs:

```week1: \$57.00 (\$14.25)
week2: \$48.40 (\$12.10)
week3: \$37.60 (\$ 9.40)
week4: \$51.00 (\$12.75)
week5: \$45.00 (\$11.25)```

To fix your problem, replace the following awk code

`grep 'foo' 2012-2013.txt | awk 'BEGIN{ sum=0.0}{ sub(",","",\$7); sum +=\$7}END{ print "\$" sum}'`

with:

`grep 'foo' 2012-2013.txt | awk 'BEGIN{ sum=0.0}{ sub(",","",\$7); sum +=\$7}END{ printf "\$%.2fn", sum}'`

You can skip the grep command and use awk as follows to match and perform sum of all \$7:

`awk '/foo/{ sub(",","",\$7); sum = old + \$7; old=sum}END{ printf "\$%.2fn", sum}' 2013-2014.txt`

The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.

20/08/2019

### Start your Bitcoin Exchange with our Software

Start your Bitcoin Exchange with our Software Setup your white label bitcoin exchange right away. Or create your own cryptocurrency using...
14/08/2019

### How to KVM, QEMU start or stop virtual machine from command line (CLI)

KVM or Kernel Based Virtual Machine is a popular virtualization technology. It allows you to run virtual guest machines over a host machine. To start...
14/08/2019

### How to Docker backup Saving and restoring your volumes

Running a Docker volume backup First, we spin up a temporary container, and we mount the backup folder and the target Docker volume to this container....