J S*_*ith 3 c# java integer-overflow
在Java中
int x = 0;
(int)(-1.0 / x) -> Integer.MinValue
(int)(1.0 / x) -> Integer.MaxValue
Run Code Online (Sandbox Code Playgroud)
但在C#中,
int x = 0;
(int)(-1.0 / x) -> Int32.MinValue
(int)(1.0 / x) -> Int32.MinValue!!
Run Code Online (Sandbox Code Playgroud)
如果使用"unchecked"语句/运算符,行为将是相同的,如果使用"checked",则它是溢出异常.
但可以肯定的是,在未经检查的上下文中,除了1.0/x(其中x = 0)之外,还会产生Int32.MaxValue,而不是Int32.MinValue.
我错过了什么吗?
Jon*_*eet 10
真的,人们不应该期待任何事情.从C#规范,第6.2.1节(强调我的):
用于转换
float或转换double为整数类型[...]. - 在未选中的上下文中,转换始终成功,并按如下方式继续.- 如果操作数的值为NaN或无穷大,则转换结果是目标类型的未指定值.
将其与Java规范进行比较,第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结果.