【问题标题】:Need help rounding to 2 decimal places需要帮助四舍五入到小数点后 2 位
【发布时间】:2012-08-24 16:18:39
【问题描述】:

为什么当我执行以下操作时...

Math.Round(0.75, 1, MidpointRounding.AwayFromZero)

我得到 0.8

但是当我执行以下操作时...

Math.Round(0.575, 2, MidpointRounding.AwayFromZero)

我没有得到 0.58。相反,我得到 0.57。我想要任何 5 及以上的四舍五入,所以 0.575 应该是 0.58。

【问题讨论】:

  • first answer in this question 应该有助于回答这个问题。
  • @KenWhite:我不确定它会不会。问题是,通过真正的数学将.575 舍入到远离零的两位小数会得到.58,但这不是观察到的结果。在这种情况下,它与浮点表示有关。
  • @Chris:你是对的。 :-) 我主要使用 Delphi,它的 Round() 在大多数情况下都可以处理这样的事情。不过,我刚刚签入了 C#,并且可以看到问题。

标签: .net vb.net math-functions


【解决方案1】:

问题在于您不能将 0.575 完全表示为二进制浮点数(例如双精度数)。虽然我并不确切知道,但似乎最接近的表示可能只是有点低,所以在四舍五入时它使用真实的表示并向下舍入。

如果您想避免此问题,请使用更合适的数据类型。 decimal 会做你想做的:

Math.Round(0.575M, 2, MidpointRounding.AwayFromZero)

结果:0.58

0.75 正确的原因是它很容易用二进制浮点表示,因为它是简单的 1/2 + 1/4(即 2^-1 +2^-2)。通常,任何 2 的有限幂和都可以用二进制浮点数表示。例外情况是您的 2 的幂跨越的范围太大(例如 2^100+2 不能完全表示)。

编辑添加:

Formatting doubles for output in C# 可能对理解为什么很难理解 0.575 不是真正的 0.575 很感兴趣。接受的答案中的 DoubleConverter 将显示 0.575 作为精确字符串是 0.5749999999999999555910790149937383830547332763671875 您可以从中看出为什么舍入给出 0.57。

【讨论】:

  • 感谢所有信息。我将我的双精度数转换为小数,就可以了。谢谢!
【解决方案2】:

System.Math.Round 方法使用Double 结构,正如其他人指出的那样,它容易出现浮点精度错误。 遇到这个问题时发现的简单解决方案是使用System.Decimal.Round 方法,它不会遇到同样的问题,也不需要将变量重新定义为小数: p>

Decimal.Round(0.575, 2, MidpointRounding.AwayFromZero)

结果:0.58

【讨论】:

    【解决方案3】:

    这是由于双精度/小数缺乏精度造成的(即 - 函数不会总是给出您期望的结果)。

    查看以下链接:MSDN on Math.Round

    以下是相关引述:

    由于将十进制值表示为浮点数或对浮点值执行算术运算可能导致精度损失,在某些情况下,Round(Double, Int32, MidpointRounding) 方法可能不会显示为舍入中点由 mode 参数指定的值。这在以下示例中进行了说明,其中 2.135 舍入为 2.13 而不是 2.14。发生这种情况是因为该方法在内部将值乘以 10 位,并且这种情况下的乘法运算会损失精度.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-03
      • 1970-01-01
      • 1970-01-01
      • 2015-11-24
      • 2012-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多