What currency rounding algorithm to use in .Net?

Is there a best practice for using .Net rounding algorithm for decimal rounding operations that takes into account internal systems? Real world experience appreciated.


.Net uses Bankers rounding by default. ( MidpointRounding.ToEven ). This contradicts the original SQL Server database that I use, since SQL Server uses arithmetic rounding ( MidpointRounding.AwayFromZero ) and does not have a built-in function to simulate Banker rounding.

Note. I use decimal code (18, 4) in SQL Server, decimal in .Net

Example .Net example by default Banker rounding with two decimal places versus rounding SQL Server to two decimal places:

| Value | .Net  | SQL Server  |
|-------|-------|-------------|
| 2.445 | 2.44  | 2.45        |
| 2.455 | 2.46  | 2.46        |
| 2.465 | 2.46  | 2.47        |
| 3.445 | 3.44  | 3.45        |
| 3.455 | 3.46  | 3.46        |
| 3.465 | 3.46  | 3.47        |

// t-sql
declare @decimalPlaces int
set @decimalPlaces = 2

select round(convert(decimal(18, 4), 2.445), @decimalPlaces) -- 2.45
select round(convert(decimal(18, 4), 2.455), @decimalPlaces) -- 2.46
select round(convert(decimal(18, 4), 2.465), @decimalPlaces) -- 2.47
select round(convert(decimal(18, 4), 3.445), @decimalPlaces) -- 3.45
select round(convert(decimal(18, 4), 3.455), @decimalPlaces) -- 3.46
select round(convert(decimal(18, 4), 3.465), @decimalPlaces) -- 3.47

// .Net
var algorithm = MidpointRounding.ToEven;
var decimalPlaces = 2;
Console.WriteLine(decimal.Round(2.445M, decimalPlaces, algorithm).ToString()); // 2.44
Console.WriteLine(decimal.Round(2.455M, decimalPlaces, algorithm).ToString()); // 2.46
Console.WriteLine(decimal.Round(2.465M, decimalPlaces, algorithm).ToString()); // 2.46
Console.WriteLine(decimal.Round(3.445M, decimalPlaces, algorithm).ToString()); // 3.44
Console.WriteLine(decimal.Round(3.455M, decimalPlaces, algorithm).ToString()); // 3.46
Console.WriteLine(decimal.Round(3.465M, decimalPlaces, algorithm).ToString()); // 3.46

- SQL Server , , .Net - Banker Rounding.

, .Net, (nopCommerce) Banker , , .


, : (MidpointRounding.AwayFromZero) .Net?

+4
4

. , " " , .

, , " ".

, , - , , , , .

MidpointRounding.ToEven . , Visual Basic ( .NET). , . , , , MidpointRounding.AwayFromZero.

, - , " ", . -, " Microsoft ", . , . , MidpointRounding.AwayFromZero. MidpointRounding.AwayFromZero.

+3

, . , . , , - .

, . , , .

. , , , , . .

+3

decimal, float / double, 2 , 10. SQL Server decimal .NET, .

RE: , ,

  • , /, , , .
  • , .

:

        Real Value  Standard    Bankers
        0.25        0.3         0.2
        0.75        0.8         0.8
-----------------------------------------
Sum     1           1.1         1

, , ,

x.5  (e.g. 6.5)

, , , 0.5 , , x , (-0,5) x , (+0,5), , +0.5 -0.5 .

, , , .

, AwayFromZero ( )

+3

, , , , .NET SQL Server, . , , , .

, , , (, 4dp) ( 2dp), Math.Round . SQL Server , ( (18,4)).

Then you can add an additional level of consistency to your user interface, it may depend on what controls you use, but you can, for example, limit the number to the appropriate number of digits, so the user does not enter for example 1.32682 if your application only saves 1.33 .

0
source

All Articles