C# - 将十进制数转换为整型(int32)

12

我有以下代码:

int a = Convert.ToInt32(4.5m);
int b = Convert.ToInt32(5.5m);

Console.WriteLine(a);
Console.WriteLine(b);

这是输出结果:

4
6
为什么 Convert.ToInt32 会将小数四舍五入到最接近的偶数?

但是,为什么期望有所不同呢? - Tigran
1
好的,我会期望a=5,b=6。 - General Grey
2
定义“最近”。4和6到5.5的距离相等。 - Oded
@tigran 因为它是不规则的,第一位向下取整,第二位向上取整。并非所有人都知道银行家舍入法 ;) - user1241335
请看我下面的回答,其中有一个关于银行家舍入的不太准确的定义。或者您可以自己研究一下,以获得更好的答案。Dirk解释了如何选择所需的舍入形式。ie的答案也很好。虽然我感觉是复制粘贴的,但解释更好。我想这是可以接受的,但在我看来,提供该信息的链接会更好。 - General Grey
显示剩余4条评论
6个回答

13

Convert方法使用四舍五入或银行家舍入法:

此方法的行为遵循IEEE标准754第4节。这种舍入有时称为四舍五入或银行家舍入,它最小化由于始终将中间值向单个方向舍入而导致的舍入误差。

若要控制Round方法使用的舍入类型,请调用Math.Round(Double, MidpointRounding)重载。


13
int a = (int)Math.Floor(4.5m);
int b = (int)Math.Floor(5.5m);

MSDN

或者:

int a = decimal.ToInt32(4.5m);
int b = decimal.ToInt32(4.5m)

您也可以使用显式的 int 强制类型转换操作符:

int a = (int) 4.5m;
int b = (int) 5.5m;

但请阅读来自MSDN的注意事项:

该运算符支持将一个Decimal类型转换为Int32类型。这种显式转换的语法因语言而异,不同的语言编译器可以提供不同的实现并返回不同的结果。该示例演示了通过使用C#和Visual Basic显式转换Decimal值为Int32值时返回不同的结果。为执行独立于语言的转换,您可以调用ToInt32或Convert.ToInt32(Decimal)方法。


Math.Floor Method (Decimal)

返回不大于指定十进制数的最大整数。

请注意,十进制数比int更大,因此如果该值大于int.MaxValue,则会引发OverflowException异常。


1
+1 哎呀!你比我快 :) 我还在等 OP 的确认。 - gideon
@K'Leg。这就是他所询问的内容。 - gdoron
@K'Leg。我一分钟前问了他,让我们看看他的回答会是什么。 - gdoron
1
@gdoron 没关系,无论如何,如果这是他想要的,他会选择这个作为答案。 - General Grey
@K'Leg。一个不错的评论,不像Ramhound的评论... :) - gdoron
显示剩余6条评论

5

Math.Round()允许您进行选择

Console.WriteLine(Math.Round(4.5m, 0, MidpointRounding.ToEven));  //4
Console.WriteLine(Math.Round(5.5m, 0, MidpointRounding.ToEven));  //6

Console.WriteLine(Math.Round(4.5m, 0, MidpointRounding.AwayFromZero));  //5
Console.WriteLine(Math.Round(5.5m, 0, MidpointRounding.AwayFromZero));  //6

(而且,正如你所猜测的那样,默认值是 ToEven

4
它这样做是因为如下原因:这就是它的定义方式
返回:四舍五入后最接近的32位有符号整数。如果value在两个整数之间,则返回偶数;也就是说,4.5转换为4,5.5转换为6。
如果您想要不同的结果,您需要使用像Math.Floor这样的方法。
执行相同操作的Math.Round文档说明了原因:
此方法的行为遵循IEEE标准754第4节。这种类型的四舍五入有时被称为最近的四舍五入或家庭银行家的四舍五入。它最小化了由于始终将中间值向单个方向舍入而导致的舍入误差。
要控制Round(Decimal)方法使用的舍入类型,请调用Math.Round(Decimal,MidpointRounding)重载。

是的,但我想知道原因 :) MSDN的解释毫无意义。 - šljaker
请看我的回答,我认为它有点解释了。Dirk展示了如何选择你想要舍入的方式。 - General Grey
@šljaker - 你的提问和期望完全不正确的结果,清楚地表明你不知道原因。此外,你问了“为什么会发生这种情况?” - Security Hound
@šljaker,我扩展了我的答案以提供解释。Convert.ToInt32(decimal)默认执行与Math.Round相同类型的四舍五入。 - Botz3000

0

我昨天读到了一些关于四舍五入的内容,它会将数字四舍五入到最接近的偶数,这被称为银行家舍入。你必须告诉它你想要如何舍入。

编辑:你要求解释为什么它会舍入到最接近的偶数。

假设你有10个数字(这是一个极端的例子)

1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5

总和 = 60

如果你先将它们四舍五入

总和 = 65,因为它们都会向上取整

如果你使用银行家舍入法

总和 = 60


这只是重复了之前的答案,没有解释为什么要使用这种舍入方法。 - Security Hound
@Ramhound 请检查回答添加的时间...他们重复了我的回答,而不是反过来,我同意我没有解释为什么,除了说明它增加了准确性,这就是为什么在我做出的其他评论中,我告诉人们阅读他们的答案。 - General Grey

0

来自http://msdn.microsoft.com/en-us/library/93kx4xke

返回值

类型:System.Int32 值,四舍五入为最接近的 32 位有符号整数。如果值恰好处于两个整数之间,则返回偶数;也就是说,4.5 转换为 4,5.5 转换为 6。


你所做的只是重复了Botz3000已经说过的话。我不明白这个回答的意义。 - Security Hound
如果您查看时间戳,就可以看到我们同时发布了。 - JonC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接