photo with hundreds of pennies on a table with a jar.

Why is Rounding so Difficult?

I was today years old when I learned that the way I learned to round in school was not how everyone rounded. I was taught that the value 1.65, when rounded to one decimal point, would result in 1.7.

Today I was manually calculating gross wages and payroll liabilities to automate a billing process at work. I noticed that several of the calculations were off by a penny and I could not figure out what was causing the issue. That is when I started to look into R’s round() function I was using.

Below is the issue I found in when scouring for penny rounding errors.

R console log showing a calculation inside of the round function rounding to three digits and then rounding to two digits. When rounding to three digits, the result is 1902.115.  When rounding to two digits, the result is 1092.11.

A quick google search was pretty enlightening. I had no idea there were different rounding standards.

Apparently, the way I learned to round only applies to commerce and money. That’s when I read about the international standard (ISO 60559) that deals “… formats and methods for floating-point arithmetic in computer systems.”

When looking at the documentation for the round() function, it states this:

“Note that for rounding off a 5, the IEC 60559 standard (see also ‘IEEE 754’) is expected to be used, ‘go to the even digit’. Therefore round(0.5) is 0 and round(-1.5) is -2. However, this is dependent on OS services and on representation error (since e.g. 0.15 is not represented exactly, the rounding rule applies to the represented number and not to the printed number, and so round(0.15, 1) could be either 0.1 or 0.2).”

I’m still not clear on why round(1902.115, 2) results in the correct rounding of 1092.12, but when you wrap the round function around a calculation, the result is the incorrect rounding of the value.

Both of the fields in my data frame that are used in the calculation are numeric:

$ ts_pay_rate    : num  36 35.9 143.8 499.5 13.9 ...
$ ts_hrs_units   : num  80 80 1 1 80 1.75 80 70 1 11 ...

> dat$ts_pay_rate[2173]
[1] 38.0423
> dat$ts_hrs_units[2173]
[1] 50


So rounding with calculations in R when using the round() function can be problematic when the evaluation digit is a 5. When you feed the round function a number, it rounds the values as expected.

My workaround for this issue works for me since I’m exporting the data to an Excel file. Instead of rounding the calculation to two digits, I round it to three, and let Excel do the rounding for me.

It’s not perfect, and I hope that I can find an answer to my question I posed on Reddit, but for now, it works.