在C#中将double转换为int


102

在我们的代码中,我们有一个double,需要将其转换为int。

double score = 8.6;
int i1 = Convert.ToInt32(score);
int i2 = (int)score;

谁能解释我为什么i1 != i2

我得到的结果是:i1 = 9i2 = 8


5
Math.Truncate(score)(int)score
Lu55

3
但是Math.Truncate返回的是双精度或十进制,而不是整数
Sergioet18年

Answers:


163

因为Convert.ToInt32回合:

返回值:舍入到最接近的32位有符号整数。如果值在两个整数之间,则返回偶数;否则,返回偶数。即4.5转换为4,5.5转换为6。

...当演员截断时

当您从double或float值转换为整数类型时,该值将被截断。

更新:请参阅下面的Jeppe Stig Nielsen的注释以了解其他差异(但是,如果score是真实数字(如此处所示),则不会起作用)。


6
您的链接实际上能最好地解释它,而不是简单地舍入或截断:类型:System.Int32值,四舍五入为最接近的32位带符号整数。如果值在两个整数之间,则返回偶数;否则,返回偶数。即,4.5转换为4,和5.5被转换为6
ericosg

@ericosg:是的,如果将掩盖的差异score8.5不是8.6。我更新了答案以包括引号。感谢您的输入。
2012年

5
如果scoreis是NaN或无限或有限但在的范围之外Int32Convert.ToInt32则将引发异常。Cast将返回int,但您不会知道哪个(在我的实现中为Int32.MinValue),因为您处于unchecked上下文中。(如果您处于checked上下文中,在这些情况下,演员表也会抛出异常。)
Jeppe Stig Nielsen

@JeppeStigNielsen:感谢您的输入,我也更新了答案以提及这一点。
2012年

真好 但是我认为Double类型数字10000000000.6(百亿分之六)是一个“真实”数字。使用强制转换int会产生奇怪的结果(除非您处于checked上下文中,但可能并非如此)。
杰普·斯蒂格·尼尔森

13

转换将忽略小数点后的任何内容,因此8.6变为8。

Convert.ToInt32(8.6) 是确保双精度数舍入到最接近的整数(在这种情况下为9)的安全方法。


1
额外的问题-如果double的值太大而无法推入int会发生什么?即是否高于int.MAX_VAL
Konrad Viltersten

1
@KonradViltersten引发异常对于Int32,值太大或太小。
瓦姆西

11

您可以四舍五入并强制转换:

(int)Math.Round(myDouble);

4
现在的问题是如何制作i1 == i2。问题是为什么它们不相等。不赞成投票。
2012年

5

在提供的示例中,您的十进制为8.6。如果是8.5或9.5,则语句i1 == i2 可能是正确的。实际上,对于8.5而言将为true,对于9.5而言将为false。

说明:

无论小数部分如何,第二条语句int i2 = (int)score都将舍弃小数部分,而只返回整数部分。这样做很危险,因为可能会发生数据丢失。

现在,对于第一个语句,可能会发生两件事。如果小数部分为5,即小数点后半部分,则要做出决定。我们是向上舍入还是向下舍入?在C#中,Convert类实现银行家的舍入。有关更多说明,请参见此答案。简而言之,如果数字为偶数,则向下取整;如果数字为奇数,则向上取整。

例如,考虑:

        double score = 8.5;
        int i1 = Convert.ToInt32(score); // 8
        int i2 = (int)score;             // 8

        score += 1;
        i1 = Convert.ToInt32(score);     // 10
        i2 = (int)score;                 // 9

2

ToInt32回合。强制转换为int只会丢弃非整数组件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.