舍入小数值
我同时使用Math.Round(a, 2);
舍入小数值
当我四舍五入1.275通过2小数点在C#四舍五入的十进制值面临的问题,结果是1.27。 当我为1.375做同样的事情时,结果是1.38。
为什么它不是1.275到1.28?
感谢
我无法重现你的问题:
Math.Round(1.275m, 2) => 1.28m
Math.Round(1.375m, 2) => 1.38m
我怀疑你的要求,你使用decimal
值是假的,那你用double
值来代替。 double
不能精确地表示许多十进制值,所以当你写1.275
时,它实际上是1.27499 ... 1.375
是少数几个可表示的元素之一,所以它实际上是1.375
。
如果你的代码在乎准确的十进制表示,例如,当你在金钱而工作,你必须使用和decimal
不是二进制浮点如double
或float
。
但是,即使你使用十进制表示,四舍五入出现意外的行为对于很多用户:
Math.Round(1.265m, 2) => 1.26m
Math.Round(1.275m, 2) => 1.28m
默认情况下Math.Round
使用MidpointRounding.ToEven
,也被称为Banker's round。这样可以避免积累总是在.5
四舍五入的偏见。
您可以使用Round
的过载采用舍入模式,并将其设置为AwayFromZero
以获得您期望的行为。
Math.Round(1.275m, 2, MidpointRounding.AwayFromZero) => 1.28m
Format(1.275, "0.00"))
在本博客的评论建议:http://weblogs.asp.net/sfurman/archive/2003/03/07/3537.aspx
你使用哪种版本的.NET框架的?如果是1.1以上,则可以使用midpointrounding并将其设置为AwayFromZero
Math.Round(1.275, 2, MidpointRounding.AwayFromZero);
http://msdn.microsoft.com/en-us/library/9s0xa85y%28v=vs.110%29.aspx
这是一个可怕的黑客,而是尝试使用格式。它莫名其妙地使用我们都习惯的四舍五入。
Val(Format(2.25, "0.0")) returns 2.3
(OR)
只为信息:从.NET版本2.0其可以定义“0.5案件”与参数MidpointRounding四舍五入的方式。它可以是ToEven或AwayFromZero。因此,“标准”舍入将如下所示:
Math.Round(2.25, 1, MidpointRounding.AwayFromZero);
这将返回值“2.3”。
MSDN有这对于这种行为说:
注呼叫者
由于精度损失可能导致从 表示十进制值作为浮点数或执行 的对浮点值进行算术运算,在某些情况下,圆形(Double,Int32)方法可能不会出现以将中点值舍入为 数字中最接近的偶数值decimal decimal posi灰。这是在以下示例中说明的 ,其中2.135四舍五入为2.13 而不是2.14。这是因为内部方法将 值乘以10 数字,并且在这种情况下 的乘法运算遭受精度损失。
public class Example
{
public static void Main()
{
double[] values = { 2.125, 2.135, 2.145, 3.125, 3.135, 3.145 };
foreach (double value in values)
Console.WriteLine("{0} --> {1}", value, Math.Round(value, 2));
}
}
// The example displays the following output:
// 2.125 --> 2.12
// 2.135 --> 2.13
// 2.145 --> 2.14
// 3.125 --> 3.12
// 3.135 --> 3.14
// 3.145 --> 3.14
如果该方法返回不正确的结果,因为它在内部执行某些不准确的操作,则实现不正确。更有可能的是,MSDN文档是错误的,Math.Round返回一个意外的结果,因为调用者没有意识到他们传递的值并不是他们想象的。例如,在这里提出的问题中,调用者没有通过1.275,而是通过了略低于1.275的值。 **在调用Math.Round之前发生错误**,而不是**在**中。 – 2012-07-31 16:59:02
如果你有Decimal
值,使其能正确一轮1.275
到1.28
。
如果您有Double
值,它将不会表现相同,因为值1.275
无法完全表示。如果您使用double
的值1.275
,它实际上会比精确值1.275
略小,如1.2749999999999999
。
四舍五入时,该值在1.27
和1.28
之间并不会很快,但会略微接近1.27
,因此它会向下舍入而不是向上。
这是因为你的四舍五入双,而不是一个小数:
Console.WriteLine(Math.Round(1.275M, 2)); // outputs 1.28
Console.WriteLine(Math.Round(1.375M, 2)); // outputs 1.38
小数和双打有很大的不同每个文档
什么与downvote和没有评论? – 2012-07-31 15:22:38
预期的行为。
例如,如果小数等于1,2.15和2.15000都 圆形至2.2,因为0.05和0.05000是0.1和 0.2中途两者之间,并且0.1为奇数。同样,如果小数等于1,则2.05和 2.05000都舍入为2.0,因为.05和.05000都在.0和.1之间,并且.0为偶数。这种方法的行为遵循IEEE标准754第4部分。这种取整有时称为舍入到最近或舍入四舍五入。它通过在单个方向上始终舍入中点值来最小化舍入误差。要控制Round(Decimal,Int32)方法所使用的舍入类型 ,请调用 Decimal.Round(Decimal,Int32,MidpointRounding)重载。
Decimal.Round(a, 2, MidpointRounding.AwayFromZero);
对不起,还没有找到截图;-)但是我找到了这个博客:http://weblogs.asp.net/sfurman/archive/2003/03/07/3537。aspx – 2012-07-31 13:18:22
你实际上是在使用'decimal'的值还是使用'double'? – CodesInChaos 2012-07-31 13:24:37
当你说你围绕“小数”值的时候,这有点令人困惑; 'Math.Round(1.275m,2)= 1.28',而如果你使用'double'超载,你在写作时会得到'Math.Round(1.275,2)= 1.27'。问题很可能是由于浮点表示的不准确。 – 2012-07-31 13:25:31