在Java中,
int x = 0;
(int)(-1.0 / x) -> Integer.MinValue
(int)(1.0 / x) -> Integer.MaxValue
但是在C#中,
int x = 0;
(int)(-1.0 / x) -> Int32.MinValue
(int)(1.0 / x) -> Int32.MinValue!!
如果"未选中"行为将是相同的。使用语句/运算符,如果"检查"而是使用它然后它是一个溢出异常。
但可以肯定的是,在未经检查的上下文中,除了1.0 / x(其中x = 0)之外,还会产生Int32.MaxValue,而不是Int32.MinValue。
我错过了什么吗?
答案 0 :(得分:10)
真的,不应该期待任何东西。从C#规范,第6.2.1节(强调我的):
从
float
或double
转换为整数类型[...]。 - 在未经检查的上下文中,转换始终成功,并按如下方式进行。 - 如果操作数的值为NaN或无穷大,则转换结果为目标类型的未指定值。
将其与Java规范进行比较,section 5.1.3:
将浮点数转换为整数类型T需要两个步骤:
在第一步中,浮点数转换为long(如果T为long)或转换为int(如果T为byte,short,char或int),如下所示:
- 如果浮点数为NaN(§4.2.3)[...],则转换的第一步结果为int或long 0。
- 否则,如果浮点数不是无穷大[...]
- 否则,以下两种情况之一必须为真:
- 该值必须太小(大幅度或负无穷大的负值),第一步的结果是int或long类型的最小可表示值。
- 值必须太大(大幅度或正无穷大的正值),第一步的结果是int或long类型的最大可表示值。
基本上,这两种语言有不同的保证,实现似乎都能满足这些保证。
我认为因为更宽松的规范,.NET JIT能够使用更高效的转换,这恰好会导致int.MinValue
。
答案 1 :(得分:7)
C#中的行为未定义。引自C# Language Specification(和this answer):
对于从float或double到整数类型的转换,处理取决于发生转换的溢出检查上下文(第7.6.12节)。在未选中的上下文中:如果操作数的值为NaN或无穷大,则转换的结果是目标类型的未指定值。