37

I am curious about the existence of any "rounding" standards" when it comes to the calculation of financial data. My initial thoughts are to perform rounding only when the data is being presented to the user (presentation layer).

If "rounded" data is then used for further calculations, should be use the "rounded" figure or the "raw" figure? Does anyone have any advice?

Please note that I am aware of different rounding methods, i.e. Bankers Rounding etc.

Guamez
  • 375
  • 1
  • 4
  • 6
  • 6
    Essential reference: http://en.wikipedia.org/wiki/Office_Space – Skilldrick Oct 01 '10 at 15:48
  • I have this vague memory of some standard from someone calling for calculations to be done in mils (i.e. $0.001, or 1./10 of a cent). But you want to talk to an accountant who knows your particular jurisdiction before you implement anything for which you or your employers might be liable. Definitely one for CPA Overflow. – dmckee --- ex-moderator kitten Oct 01 '10 at 17:00

5 Answers5

20

The first and most important rule: use a decimal data type, never ever binary floating-point types.

When exactly rounding should be performed can be mandated by regulations, such as the conversion between the Euro and national currencies it replaced.

If there are no such rules, I'd do all calculations with high precision, and round only for presentation, i.e. not use rounded values for further calculations. This should yield the best overall precision.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • 2
    Binary floating would be better than decimal with too little precision. $100⅔ is better represented in base 2 as "100.66666666666?????" than in base 10 as "100.67". But given enough decimal precison, I agree that a decimal data type is usually better. – Joe Koberg Oct 01 '10 at 19:20
  • 10
    @Joe: No, 100.67 would almost always be better because it's what people expect - and, more importantly, using a decimal type ensures that 100.01+100.07 = 100.08 rather than 200.07999999999998 – Michael Borgwardt Oct 01 '10 at 19:52
  • 2
    The time for producing what people expect is at display time, and when rounding is performed there (e.g. '%0.2f'), people will see what they expect. if you are doing intermediate calculations, I think it is inappropriate to truncate/round to only 2 digits of precision. (Of course this depends on the computation at hand. Daily interest calculation rounded to 2 places might add 0.00 to the account every day. But customer invoice doesn't need 15 places of precision.) – Joe Koberg Oct 01 '10 at 19:56
  • 1
    I just checked, our core (mainframe) software stores 6 to 8 decimal places of precision for interest accrual on each account. At the end of the month the accrual field is rounded and applied to the balance. The goal is to always have "breathing room" of a couple extra digits. My point is that running up against the precision limit is worse than binary inexactness. (Even the decimal number will be inexact if you've exceeded the precision) – Joe Koberg Oct 01 '10 at 20:10
  • 3
    @Joe: None of that changes the fact that binary floats are unacceptable for financial calculations because they cannot accurately represent most decimal fractions at all and will introduce rounding errors in a completely unpredictable manner. Fortunately, it's a non-issue because any decimal type worth using will provide far more than 2 fractional digits if required. – Michael Borgwardt Oct 01 '10 at 20:16
  • 1
    Right, neither can a 2-place decimal precision reproduce most decimal fractions. Thats my only point, and I definitely recognize the value of decimal over binary in this situation. – Joe Koberg Oct 01 '10 at 20:17
  • 8
    I am not sure about "not use rounded values for further calculations", eg, tax for item 1 is $0.012 and item 2 is $0.015, so when you display them in a statement, $0.01 and $0.01, which visually you get $0.02 in total tax, but if you add them with precision which gives $0.025, when you display that you get $0.03 – James Lin Jan 04 '15 at 19:56
  • If you know what you're doing, you can use floating point for currency just fine, including the implementation of pencil-and-paper rounding rules based on the decimal system. – Kaz Aug 06 '20 at 23:30
  • @Kaz for those who don't know what they're doing, can you point towards any good resources on how to use floating point for currency? – GordonAitchJay Dec 13 '20 at 23:40
  • 1
    @GordonAitchJay First of all, we note that a IEEE double has 15 "guaranteed" decimal digits of precision. A decimal number that is within the ridiculously wide range of the type, and that has 15 decimal digits of precision or less, can be converted to a double without loss of digits. An ordinary, non-astronomical monetary amount expressed down to the cent is approximated by a double with ridiculous precision. The error is in the 16th or 17th digit, which follows a good many zeros. – Kaz Dec 14 '20 at 04:43
  • 1
    @GordonAitchJay It takes many floating-point operations before the error accumulates so badly that the result is now close to the wrong cent. All we have to do is round every result to the closest cent after every elementary calculation. – Kaz Dec 14 '20 at 04:47
20

I just asked a greybeard mainframe programmer at the financial software company I work for, and he said there is no well-known standard and it's up to programmer practice.

While statisticians have been aware of the rounding issue since at least 1906, it's difficult to find a financial standard endorsing it.

According to this site, the "European Commission report The Introduction of the Euro and the Rounding of Currency Amounts suggests that there had previously been no standard approach to rounding in banking."

In general, use a symmetric rounding mode no matter what base you are working in (base-2 or base-10).

This will avoid systematic bias during calculations.

Such a mode is Round-Half-To-Even, otherwise known as "bankers rounding".

Use language tools that allow you to specify the numeric context explicity, including the rounding and truncation modes. For example, Python's decimal module. The implicit assumptions made by the C library might not be appropriate for your computations.

http://en.wikipedia.org/wiki/Rounding#Rounding_to_integer

Joe Koberg
  • 25,416
  • 6
  • 48
  • 54
  • 1
    The Euro standard you linked mandates that half is rounded “up” (whatever that means) which seems to forbid unbiased rounding. – Doradus Nov 23 '17 at 12:49
  • @Doradus you are incorrect, the article says you should round up/down to nearest value – Caner Feb 25 '20 at 09:55
  • 1
    @Caner - There is no "nearest value" for half. Half is to be rounded up according to this document: https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=LEGISSUM:l25025&from=FR "If the application of the conversion rate gives a result which is exactly half-way, the sum is rounded up." – Doradus Feb 26 '20 at 01:44
  • 1
    @Doradus Thanks, now I understood what you meant – Caner Feb 26 '20 at 12:27
10

It's frustrating that there aren't clear standards on this, both to guide the programmer, and as a defense in court. Just doing "regular" rounding toward nearest for payroll can lead to underpayment by a few pennies on a paycheck here and there, which is something labor lawyers eat up like crack.

Though a base pay rate may well only be specified in two decimal places ("You're hired at $22.71/hour"), things like blended overtime (determined by averaging multiple pay rates in a period) end up with an effective hourly rate of $23.37183475/hr.

How do you pay overtime on that?

15 hours x 23.37183475 x 1.5 = $525.87 rounded from $525.86628187
15 hours x 23.37       x 1.5 = $525.82

WHY DID YOU STEAL FIVE CENTS FROM MY CLIENT? Sadly, I'm not joking about this.

This gets even more uncomfortable when you calculate at the full precision value but display a truncated version: you do the first calculation above, but only display $23.37 for the rate on the pay stub.

Now the pay stub calculations don't tie out to the penny, and now you have to explain it, but even if it's in the employee's favor, it can be enough for a labor lawyer to smell blood in the water and start looking for other stuff.

One approach is to always round in favor of the employee, not in the natural direction, so there cannot ever be an accusation of systematic wage theft.

Steve Friedl
  • 3,929
  • 1
  • 23
  • 30
3

Ive not seen the existence of "the one standard to rule them all" - there are any number of rounding rules (as you have referenced), and they seem to come into play based on industry/customer/and currency code (http://en.wikipedia.org/wiki/ISO_4217) - since not everyone uses 2 places after the decimal, the problem becomes even more complicated. At the end of the day, your customer needs to specify the rules they want to implement...

jbr
  • 6,198
  • 3
  • 30
  • 42
chrismh
  • 131
  • 4
0

Consider using scaled integers.

In other words, store whole numbers of pennies instead of fractional numbers of dollars.

Beth
  • 9,531
  • 1
  • 24
  • 43
  • 15
    Nope, that only pushes the problem out by twp decimal points. What do you do when it's time to add 5% to $1.23? – Doradus Oct 12 '15 at 14:48
  • 1
    Storing in a currency's smallest unit (pennies in most cases) has a number of advantages - whatever rounding strategy you decide to use would apply equally. – Optimae May 25 '18 at 00:46