四舍五入

Osk*_*erg 10 .net c#

我有这个"科学应用程序",其中Single值应该在UI中呈现之前进行舍入.根据这篇MSDN文章,由于"精度损失",该Math.Round(Double, Int32)方法有时会"意外地"表现,例如将2.135舍入到2.13而不是2.14.

据我了解,这个问题与"银行家的四舍五入"无关(参见例如这个问题).

在应用中,有人显然选择了通过显式转换来解决这个问题Single,以一个Decimal舍入(即之前Math.Round((Decimal)mySingle, 2))来调用Math.Round(Decimal, Int32)过载来代替.除了可能出现的二进制到十进制转换问题之外,OverflowException如果该Single值太小或太大而不适合该Decimal类型,则该"解决方案"也可能导致抛出.

Math.Round(Double, Int32)如果转换失败,捕获此类错误以返回结果,并不会使我成为完美的解决方案.也不会重写应用程序以便一直使用Decimal.

是否有或多或少"正确"的方式来处理这种情况,如果是这样,它可能是什么?

thi*_*rge 0

我刚刚查看了文档,似乎有一个可以传递到的枚举Math.Round()。如果你更改为Math.Round(Double, Int32, MidpointRounding.AwayFromZero)你应该得到想要的结果。

https://msdn.microsoft.com/en-us/library/vstudio/ef48waz8(v=vs.100).aspx

编辑:刚刚用这些数字进行了测试。更改了数字和

    double abc = 2.335;
    Console.WriteLine(Math.Round(abc, 2, System.MidpointRounding.AwayFromZero));        
    abc = 2.345;
    Console.WriteLine(Math.Round(abc, 2, System.MidpointRounding.AwayFromZero));

    abc = 2.335;
    Console.WriteLine(Math.Round(abc, 2));      
    abc = 2.445;
    Console.WriteLine(Math.Round(abc, 2));
Run Code Online (Sandbox Code Playgroud)

并得到了这些结果。

2.34
2.35
2.34
2.44
Run Code Online (Sandbox Code Playgroud)

编辑 2:我使用了您提供的原始数字,但它已损坏。我认为通过使用 AwayFromZero 可以解决双舍入问题(我认为它仅适用于银行家舍入),但事实并非如此。如果您确实需要从舍入中寻找的精度,则必须创建自己的函数,通过转换为 double 或其他方法来为您提供所需的精度,但我已经寻找了一段时间但还没有发现任何东西,我会回来看看你是否能找到解决方案。

double abc = 2.135;
Console.WriteLine(Math.Round(abc, 2, System.MidpointRounding.AwayFromZero));        
abc = 2.145;
Console.WriteLine(Math.Round(abc, 2, System.MidpointRounding.AwayFromZero));

abc = 2.135;
Console.WriteLine(Math.Round(abc, 2));      
abc = 2.145;
Console.WriteLine(Math.Round(abc, 2));

2.13
2.15
2.13
2.14
Run Code Online (Sandbox Code Playgroud)