对于超出整数范围的数字,整数类型转换如何在Java中表现?

Lon*_*ner 39 java casting

这是我的计划.

public class Foo
{
    public static void main(String[] args)
    {
        System.out.println((int) 2147483648l);
        System.out.println((int) 2147483648f);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是输出.

-2147483648
2147483647
Run Code Online (Sandbox Code Playgroud)

为什么不2147483648l2147483648f类型转换为相同的整数?你能解释一下这里发生了什么,或者我需要了解Java中的哪些概念来预测像这样的类型转换的输出?

T.J*_*der 75

这些是Narrowing Primitive Conversion操作的示例.

在您的第一个示例中,longint:

将有符号整数缩小到整数类型T只会丢弃除n个最低位之外的所有位,其中n是用于表示类型T的位数.除了可能丢失有关数值大小的信息之外,这可能导致结果值的符号与输入值的符号不同.

所以你(int) 2147483648l的64位是long:

00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000000

...并完全删除前32位:

10000000 00000000 00000000 00000000

...并将剩余的32位作为int.由于最左边的那些现在是一个符号位(longint存储为两个补码),并且因为它恰好设置在您的2147483648l值中,所以最终会得到一个负数.由于没有设置其他位,在二进制补码中,这意味着您具有最低负数int可以表示:-2147483648.

floatint示例遵循更复杂的规则.您的价值的相关部分是:

...如果浮点数不是无穷大,浮点值将四舍五入为整数值V,使用IEEE 754舍入零模式(§4.2.3)向零舍入.

... [if]值[is]太大(大幅度或正无穷大的正值),[then]第一步的结果是int或long类型的最大可表示值.

(但请参阅上面链接的规范部分以获取详细信息.)

因此,由于2147483648f舍入为21474836482147483648太大而无法放入int,因此使用int(2147483647)的最大值.

所以在longto int,它有点摆弄; 在floatto中int,它更具数学性.


在评论中你问过:

你知道为什么两个(short) 32768(short) 32768f评价-32768?我正在考虑后者来评估32767.

很好的问题,这就是我的"看到上面链接的细节部分的细节"来自.:-) (short) 32768f实际上,(short)(int)32768f:

在上面链接的规范部分中,在"将浮点数转换为整数类型T需要两个步骤:",它说

  1. 在第一步骤中,浮点数会被转换成一个long,如果T是long,或一个int,如果T是byte,short,char,或int...

然后在第2步的第二个子弹中:

  1. *如果T是byte,, char或者short,转换的结果是第一步结果的类型T(第5.1.3节)的缩小转换的结果.

所以在第一步中,32768f变成32768(一个int值),然后当然(short)32768是我们在long=> int上面看到的位斩波,给我们一个short-32768.

  • 一个很好的答案.Upvoted - 我们不希望OP被诱惑接受我的. (2认同)
  • 这适用于其他语言吗?C#? (2认同)
  • @MarioGarcia:不会.每种语言都围绕着它定义了自己的语义.在C#中,问题中的两个强制转换都会导致`-2147483648`(并且都需要`unchecked`包装器). (2认同)

Bat*_*eba 20

太好了!很高兴看到设计决策的效果以您的方式呈现.

2147483648l是一种long类型和规则的转换long这是过大,int是应用环绕成冶目标类型.(在引擎盖下,源类型的重要位被简单地丢弃.)

2147483648f是一种float类型,并且用于转换对于目标类型来说太大的规则float为目标类型采用尽可能大的规则.引用是否在转换类型的MAX_INT处将Java整数类型基元强制转换为"上限"?

关于标准的好处是有很多可供选择的.

  • 至少行为是在语言规范中完全定义的,而不是留给实现. (10认同)
  • @Bathsheba取决于你来自哪里.对我而言,它比获得不同的结果要好得多,因为我并不关心创建VM有多困难.但如果你的工作正是如此,我可以看到严格的规范是多么痛苦.虽然不一定在这个领域,因为这是一个极其罕见的场景,更多的是"一切都必须是大端"的规则. (7认同)
  • @biziclop:我个人认为这是一个缺点 - 你可能需要将"生活日光"从"异国情调"架构的CPU中烧掉,这样才能符合这一要求. (3认同)