.net 需要帮助四舍五入到小数点后两位

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12113096/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 16:35:27  来源:igfitidea点击:

Need help rounding to 2 decimal places

.netvb.netmath-functions

提问by Steve B

Why is it that when I do the following...

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

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

I get 0.8

我得到 0.8

but when I do the following...

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

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

I don't get 0.58. Instead I get 0.57. I want anything that is 5 and up rounding up, so 0.575 should be 0.58.

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

回答by Chris

The problem will be that you cannot represent 0.575 exactly as a binary floating point number (eg a double). Though I don't know exactly it seems that the representation closest is probably just a bit lower and so when rounding it uses the true representation and rounds down.

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

If you want to avoid this problem then use a more appropriate data type. decimalwill do what you want:

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

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

Result: 0.58

结果: 0.58

The reason that 0.75 does the right thing is that it is easy to represent in binary floating point since it is simple 1/2 + 1/4 (ie 2^-1 +2^-2). In general any finite sum of powers of two can be represented in binary floating point. Exceptions are when your powers of 2 span too great a range (eg 2^100+2 is not exactly representable).

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

Edit to add:

编辑添加:

Formatting doubles for output in C#might be of interest in terms of understanding why its so hard to understand that 0.575 is not really 0.575. The DoubleConverter in the accepted answer will show that 0.575 as an Exact String is 0.5749999999999999555910790149937383830547332763671875You can see from this why rounding give 0.57.

在理解为什么很难理解 0.575 并不是真正的 0.575 方面,在 C# 中为输出格式化双精度可能会很有趣。接受的答案中的 DoubleConverter 将显示 0.575 作为精确字符串是0.5749999999999999555910790149937383830547332763671875您可以从中看出为什么舍入给出 0.57。

回答by Antagony

The System.Math.Roundmethod uses the Doublestructure, which, as others have pointed out, is prone to floating point precision errors. The simple solution Ifound to this problem when I encountered it was to use the System.Decimal.Roundmethod, which doesn't suffer from the same problem and doesn't require redifining your variables as decimals:

System.Math.Round方法使用的Double结构,正如其他人指出的那样,容易出现浮点精度错误。简单的解决办法发现这个问题我遇到过,当它是使用System.Decimal.Round方法,它不会有同样的问题,并不需要redifining您的变量小数:

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

Result: 0.58

结果:0.58

回答by Jason

It is caused by a lack of precision with doubles / decimals (i.e. - the function will not alwaysgive the result you expect).

它是由双精度/小数精度​​不足引起的(即 - 该函数不会总是给出您期望的结果)。

See the following link: MSDN on Math.Round

请参阅以下链接:MSDN on Math.Round

Here is the relevant quote:

这是相关的报价:

Because of the loss of precision that can result from representing decimal values as floating-point numbers or performing arithmetic operations on floating-point values, in some cases the Round(Double, Int32, MidpointRounding) method may not appear to round midpoint values as specified by the mode parameter.This is illustrated in the following example, where 2.135 is rounded to 2.13 instead of 2.14.This occurs because internally the method multiplies value by 10digits, and the multiplication operation in this case suffers from a loss of precision.

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