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



这是我的程序。

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

这是输出。

-2147483648
2147483647

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

这些是缩小基元转换操作的示例。

在第一个示例中,longint

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

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

00000000 00000000 00000000 00000000 10000000 00000000 000000000 000000000...并完全删除前 32 位:

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

int示例的float遵循更复杂的规则。您的价值的相关部分是:

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

。[如果]值太大(大量级或正无穷大的正值),[则]第一步的结果是int或long类型的最大可表示值。

(但有关详细信息,请参阅上面链接的规范部分。

所以由于2147483648f舍入2147483648,而2147483648太大而无法容纳int,所以使用int的最大值(2147483647)。

所以在longint,有点摆弄;在floatint,它更

数学化。

在评论中,您问:

你知道为什么(short) 32768(short) 32768f都评估为-32768吗?我正在执行后者以评估32767.

很好的问题,这就是我上面"有关详细信息,请参阅上面链接的规范部分">的地方。 实际上,(short) 32768f确实(short)(int)32768f

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

  1. 在第一步中,浮点数被转换为long,如果T是long,或者如果T是byteshortcharint,则转换为int

然后在步骤 2 的第二个项目符号中:

  1. * 如果 T 是bytecharshort,则转换的结果是缩小到第一步结果的类型 T (§5.1.3) 的结果。

因此,在第一步中,32768f变为32768(int值),然后(short)32768当然执行我们在上面的long=>int中看到的位斩波,给我们一个short-32768.

很好!很高兴看到以您拥有的方式呈现设计决策的效果。

2147483648llong类型,转换对于int来说太大的long的规则是将环绕规则应用于目标类型。(在后台,源类型中的重要位将被简单地丢弃。

2147483648f是一种float类型,转换对于目标类型来说太大的float的规则是,对目标类型采用尽可能大的容量。参考 Java 整数类型基元强制转换是否在转换类型的MAX_INT处"封顶"?

标准的好处是有很多可供选择。

最新更新