Click here to Skip to main content
15,890,609 members
Articles / Programming Languages / C#
Tip/Trick

Rounding Up values ()- The Coder's Dilemma

Rate me:
Please Sign up or sign in to vote.
4.27/5 (3 votes)
5 Jan 2016CPOL3 min read 8.8K   3
How rounding up values cause troubles in calculations

Introduction

Recently, I came across a problem of data mismatch in case of rounding off decimal values. The problem with rounding off seems like a known flaw and many coders have taken its related issues very seriously. For the introduction, the industry has many standards for rounding off. All work fine in their respective domain except for the middle point. For example, if I am rounding up 4.5 (exact middle) to decimal placed up to 0, what should be 4 or 5. For this agenda, many algorithms are present. Most work towards the nearest value, some work towards the away from a certain point (0 or infinity), some work on the rounding off to always even/odd. But still, we have certain issues. I am discussing two here.

Key Points

  1. I am using Banker’s calculation for Rounding off, which always results in nearest even number is case of middle point. For more details, consider this link.
  2. Examples that are provided are real cases, there are already solutions provided to them. They are used here just for clarifying the issues.

#Example 1

The first example is a simple one. I am just rounding a single decimal number, but with 2 different processes. See the code.

C#
static void Main(string[] args)
{
    decimal Original = new decimal();
    Original = (decimal)4.549;
    decimal firstVal = Math.Round(Original, 2);
    decimal SecondVal= Math.Round(firstVal, 1);
    Decimal Direct = Math.Round(Original, 1);
}
Result-                  SecondVal =4.6
                         Direct =4.5

This is the same way we actually do rounding day by day. See SecondVal First rounding off shows our daily life to life method. We pick one last digit, process it, modify second last, then delete last and again go for rounding for next digit. However, if we go directly to rounding off, see Direct, the result is slightly different. This is due to the calculation that is done directly on data, whereas in the first case, we have a loss of information at step firstVal.

This can further go to disaster if I again round off these 2 values. The difference with escalate to 1.

#Example 2

There is one more particular scenario where the values at edges cause blunders for developers. I personally came across such a scenario. The case generated when we were working on a report generation segment for the transactions done by our portal (Indonesian Rupiah to Dollar specifically).

At the time of transaction, the items were paid in Indonesian Rupiah, at our end we store 2 values, rate of conversion and dollar equivalent after round off value of Rupiah (It was an already running live code, and our portal internally works in Dollar). Now reports were to be generated for user’s trace, and amounts needed to be displayed in Rupiah. We multiplied 2 values that were in the database, but the result was very different with respect to actual transaction. We got difference in hundreds. By the way, it was testing environment so we were also checking boundary values and extreme edges.

Here is a small code portal replicating the same thing. Suppose the amount is 4.445 Rupiah and the rate of conversion is 13000.

C#
static void Main(string[] args)
{
    decimal ab = new decimal();
    ab = (decimal)4.445;
    decimal Round1 = Math.Round(ab, 2);
    decimal c = ab / 13000;
    decimal d = c * 13000;
    decimal Round2 = Math.Round(d,2);
}
Result-                  Round1=4.44
                         Round2=4.45

Round1 and round2 have a difference of .01, causing an error of around 130 Indonesian Rupiah (It is just a testing scenario data, not actual live example).

Again, we had to change the existing system at our end to deal with this problem.

I hope the readers will take hints about being attentive while using round off, and will check some boundary cases. Suggestions are always invited for any mess in the tip or any improvements.

History

  • 6-Jan-2016: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer adobe
India India
Software developer and product designer, writer (both technical and non-technical)
Researcher at heart, engineer by mind Smile | :)

Comments and Discussions

 
Questiondecimal part and integer part and using digits Pin
david2006es7-Jan-16 23:08
david2006es7-Jan-16 23:08 
GeneralRe: decimal part and integer part and using digits Pin
Anant Beriwal8-Jan-16 7:33
professionalAnant Beriwal8-Jan-16 7:33 
QuestionRounding in financial systems must not be handled with floating point numbers! Pin
AndyHo7-Jan-16 9:38
professionalAndyHo7-Jan-16 9:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.