Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# banker's rounding error

double a = 18.565
return Math.Round(a,2)

..returns 18.57.
For every other number I tried banker's rounding worked as expected, for example Math.Round(2.565,2) returned 2.56.

Any clue why and when that happens? Is it error or am I missing something about banker's rounding?

Thanks..

like image 566
Damir Avatar asked Sep 23 '10 06:09

Damir


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

Is C language easy?

Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.


1 Answers

As Matthew said, 18.565 can't be accurately represented. The actual value used is 18.565000000000001278976924368180334568023681640625 (found using DoubleConverter), which is clearly beyond half-way. Now I've a sneaking feeling that sometimes Math.Round will consider a value which is actually beyond the half-way point, but which is as close to the half-way point as can be accurately represented, as being exactly at that point. However, I haven't seen any documentation describing the situations in which that's applied, and clearly it's not happening in this case. I wouldn't want to rely on it.

Even the rounded value isn't exactly 18.57 of course. It's actually 18.57000000000000028421709430404007434844970703125.

Fundamentally, if you really, really care about representing decimal values accurately, you should be using decimal. That's not just in terms of Math.Round - it goes to every aspect of handling floating point values.

That does give the right value for Math.Round, of course:

decimal m = 18.565m;
Console.WriteLine(Math.Round(m, 2)); // Prints 18.56
like image 87
Jon Skeet Avatar answered Oct 12 '22 03:10

Jon Skeet