为什么 CLR 会溢出 Int32.MaxValue ->单身-> int32,哪里的JVM没有?

发布于 2024-09-30 01:15:44 字数 799 浏览 6 评论 0原文

我在将 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

温柔女人霸气范 2024-10-07 01:15:44

这种情况由 §5.1.3< 明确处理Java 语言规范的 /a>:

a 的缩小转换
浮点数转整数
类型 T 需要两个步骤:

  1. 第一步,浮点数转换
    要么是 long,如果 T 很长,要么是
    int,如果 T 是 byte、short、char 或
    int,如下:

    • 如果浮点数为 NaN(第 4.2.3 节),则结果为
      转换的第一步是 int
      或长 0。
    • 否则,如果浮点数不是
      无穷大,浮点值为
      四舍五入为整数值 V,
      使用 IEEE 754 向零舍入
      向零舍入模式(第 4.2.3 节)。然后
      有两种情况:

      • 如果T很长,并且这个整数值可以表示为
        long,然后是第一个的结果
        step 是长值 V。
      • 否则,如果这个整数值可以表示为 int,
        那么第一步的结果就是
        int 值 V。
    • 否则,必须满足以下两种情况之一:
      • 该值必须太小(大幅度的负值
        或负无穷大),以及结果
        第一步的值是最小的
        int 类型的可表示值或
        长。
      • 该值必须太大(大幅度的正值
        或正无穷大),以及结果
        第一步是最大的
        int 类型的可表示值或
        长。

This case is explicitly handled by §5.1.3 of the Java Language Specification:

A narrowing conversion of a
floating-point number to an integral
type T takes two steps:

  1. In the first step, the floating-point number is converted
    either to a long, if T is long, or to
    an int, if T is byte, short, char, or
    int, as follows:

    • If the floating-point number is NaN (§4.2.3), the result of the
      first step of the conversion is an int
      or long 0.
    • Otherwise, if the floating-point number is not an
      infinity, the floating-point value is
      rounded to an integer value V,
      rounding toward zero using IEEE 754
      round-toward-zero mode (§4.2.3). Then
      there are two cases:

      • If T is long, and this integer value can be represented as a
        long, then the result of the first
        step is the long value V.
      • Otherwise, if this integer value can be represented as an int,
        then the result of the first step is
        the int value V.
    • Otherwise, one of the following two cases must be true:
      • The value must be too small (a negative value of large magnitude
        or negative infinity), and the result
        of the first step is the smallest
        representable value of type int or
        long.
      • The value must be too large (a positive value of large magnitude
        or positive infinity), and the result
        of the first step is the largest
        representable value of type int or
        long.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文