Ste*_*e B 20 .net vb.net math-functions
为什么当我做以下事情时......
Math.Round(0.75, 1, MidpointRounding.AwayFromZero)
Run Code Online (Sandbox Code Playgroud)
我得到0.8
但是当我做以下事情时......
Math.Round(0.575, 2, MidpointRounding.AwayFromZero)
Run Code Online (Sandbox Code Playgroud)
我不懂0.58.相反,我得到0.57.我想要任何5和更高的东西,所以0.575应该是0.58.
Chr*_*ris 34
问题是你不能将0.575完全表示为二进制浮点数(例如双精度).虽然我不确切地知道最接近的表示可能只是稍微低一点,因此在舍入时使用真实表示并向下舍入.
如果要避免此问题,请使用更合适的数据类型.decimal会做你想做的事:
Math.Round(0.575M, 2, MidpointRounding.AwayFromZero)
Run Code Online (Sandbox Code Playgroud)
结果: 0.58
0.75做正确的事情的原因是它很容易用二进制浮点表示,因为它是简单的1/2 + 1/4(即2 ^ -1 + 2 ^ -2).通常,任何有限的2的幂的和可以用二进制浮点表示.例外情况是当你的2的幂超过一个范围时(例如2 ^ 100 + 2不能完全表示).
编辑添加:
在理解为什么它很难理解0.575不是真正的0.575时,格式化C#输出的双精度可能是有意义的.接受的答案中的DoubleConverter将显示0.575作为精确字符串0.5749999999999999555910790149937383830547332763671875您可以从中看到为什么舍入给出0.57.
该System.Math.Round方法使用该Double结构,正如其他人所指出的那样,该结构易于出现浮点精度误差.简单的解决办法我发现这个问题时,我遇到的是使用System.Decimal.Round方法,它不会有同样的问题,并不需要redifining您的变量小数:
Decimal.Round(0.575, 2, MidpointRounding.AwayFromZero)
Run Code Online (Sandbox Code Playgroud)
结果:0.58
| 归档时间: |
|
| 查看次数: |
96728 次 |
| 最近记录: |