为什么 CLR 会溢出 Int32.MaxValue ->单身-> int32,哪里的JVM没有?
我在将 Int32.MaxValue
往返到 System.Single
中时遇到了意外结果:
Int32 i = Int32.MaxValue;
Single s = i;
Int32 c = (Int32)s;
Debug.WriteLine(i); // 2147483647
Debug.WriteLine(c); // -2147483648
我意识到它一定溢出了,因为 Single
尾数中没有足够的位来保存 Int32
值,因此会向上舍入。当我在 IL 中将 conv.r4
更改为 conv.r4.ovf
时,会引发 OverflowExcpetion
。很公平...
但是,当我调查这个问题时,我用 java 编译了这段代码并运行它并得到以下结果:
int i = Integer.MAX_VALUE;
float s = (float)i;
int c = (int)s;
System.out.println(i); // 2147483647
System.out.println(c); // 2147483647
我对 JVM 不太了解,但我想知道它是如何做到这一点的。这似乎并不令人惊讶,但在四舍五入到 2.14748365E9 后它是如何保留多余的数字的呢?它是否保留某种内部表示形式,然后在转换回 int 时替换它?或者它只是向下舍入到 Integer.MAX_VALUE
以避免溢出?
I ran into an unexpected result in round-tripping Int32.MaxValue
into a System.Single
:
Int32 i = Int32.MaxValue;
Single s = i;
Int32 c = (Int32)s;
Debug.WriteLine(i); // 2147483647
Debug.WriteLine(c); // -2147483648
I realized that it must be overflowing, since Single
doesn't have enough bits in the significand to hold the Int32
value, and it rounds up. When I changed the conv.r4
to conv.r4.ovf
in the IL, an OverflowExcpetion
is thrown. Fair enough...
However, while I was investigating this issue, I compiled this code in java and ran it and got the following:
int i = Integer.MAX_VALUE;
float s = (float)i;
int c = (int)s;
System.out.println(i); // 2147483647
System.out.println(c); // 2147483647
I don't know much about the JVM, but I wonder how it does this. It seems much less surprising, but how does it retain the extra digit after rounding to 2.14748365E9? Does it keep some kind of internal representation around and then replace it when casting back to int
? Or does it just round down to Integer.MAX_VALUE
to avoid overflow?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这种情况由 §5.1.3< 明确处理Java 语言规范的 /a>:
This case is explicitly handled by §5.1.3 of the Java Language Specification: