在 C# 中将 double 转换为 int
Posted
技术标签:
【中文标题】在 C# 中将 double 转换为 int【英文标题】:Converting a double to an int in C# 【发布时间】:2012-06-01 00:38:08 【问题描述】:在我们的代码中,我们需要将一个 double 转换为 int。
double score = 8.6;
int i1 = Convert.ToInt32(score);
int i2 = (int)score;
谁能解释我为什么i1 != i2
?
我得到的结果是:i1 = 9
和 i2 = 8
。
【问题讨论】:
Math.Truncate(score)
比(int)score
更明确地表达意图
但是 Math.Truncate 返回一个双精度或小数,而不是一个整数
【参考方案1】:
因为Convert.ToInt32
回合:
返回值:四舍五入到最接近的 32 位有符号整数。如果值 在两个整数之间,返回偶数; 即4.5转4,5.5转6。
...而演员truncates:
当您从双精度或浮点值转换为整数类型时, 值被截断。
更新:有关其他差异,请参阅下面 Jeppe Stig Nielsen 的评论(但是,如果 score
是一个实数,就像这里的情况一样,这些差异就不会起作用)。
【讨论】:
你的链接实际上解释得最好,它不像round vs truncate那么简单:类型:System.Int32值,四舍五入到最接近的32位有符号整数。如果 value 在两个整数的中间,则返回偶数;即4.5转4,5.5转6。 @ericosg:是的,如果score
是8.5
而不是8.6
,那将掩盖差异。我更新了答案以包含引号。感谢您的意见。
如果score
是NaN
或无穷大或有限但超出Int32
的范围,那么Convert.ToInt32
将抛出异常。 Cast 将返回一个int
,但你不会知道是哪一个(在我的实现中它是Int32.MinValue
),因为你在unchecked
上下文中。 (如果你在 checked
上下文中,在这些情况下,演员表也会抛出异常。)
@JeppeStigNielsen:感谢您的输入,我更新了答案以提及这一点。
不错。但我认为Double
类型数字10000000000.6
(百亿点六)是一个“真实”数字。使用对int
的强制转换会产生奇怪的结果(除非你在checked
上下文中,但你可能不是)。【参考方案2】:
铸造将忽略小数点后的任何内容,因此 8.6 变为 8。
Convert.ToInt32(8.6)
是确保你的 double 被四舍五入到最接近的整数的安全方法,在本例中为 9。
【讨论】:
额外问题 - 如果 double 的值太大而无法推入 int 会发生什么? IE。如果它高于 int.MAX_VAL? @KonradViltersten 引发异常 对于 Int32 而言,值太大或太小。【参考方案3】:你可以把你的替身和演员四舍五入:
(int)Math.Round(myDouble);
【讨论】:
现在的问题是如何制作i1 == i2
。问题是关于为什么他们不相等。投反对票。【参考方案4】:
在提供的示例中,您的小数是 8.6。如果它是 8.5 或 9.5,那么声明 i1 == i2 可能是正确的。事实上,对于 8.5 来说它是真的,而对于 9.5 来说它是假的。
说明:
不管小数部分如何,第二条语句int i2 = (int)score
将丢弃小数部分并简单地返回整数部分。这样做非常危险,因为可能会发生数据丢失。
现在,对于第一个语句,可能会发生两件事。如果小数部分是5,也就是半途而废,就要做出决定。我们向上还是向下取整?在 C# 中,Convert 类实现银行家的舍入。请参阅this 答案以获得更深入的解释。简单来说,如果是偶数,则向下取整,如果是奇数,则向上取整。
例如考虑:
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
【讨论】:
【参考方案5】:ToInt32 轮。转换为 int 只会丢弃非整数组件。
【讨论】:
以上是关于在 C# 中将 double 转换为 int的主要内容,如果未能解决你的问题,请参考以下文章
如何在Android中将double转换为int? [复制]
如何在 Swift 中将数据转换为 Doubles、Ints 和 Strings 等类型?