这是我的计划.
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)
为什么不2147483648l和2147483648f类型转换为相同的整数?你能解释一下这里发生了什么,或者我需要了解Java中的哪些概念来预测像这样的类型转换的输出?
T.J*_*der 75
这些是Narrowing Primitive Conversion操作的示例.
在您的第一个示例中,long要int:
将有符号整数缩小到整数类型T只会丢弃除n个最低位之外的所有位,其中n是用于表示类型T的位数.除了可能丢失有关数值大小的信息之外,这可能导致结果值的符号与输入值的符号不同.
所以你(int) 2147483648l的64位是long:
00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000000
...并完全删除前32位:
10000000 00000000 00000000 00000000
...并将剩余的32位作为int.由于最左边的那些现在是一个符号位(long并int存储为两个补码),并且因为它恰好设置在您的2147483648l值中,所以最终会得到一个负数.由于没有设置其他位,在二进制补码中,这意味着您具有最低负数int可以表示:-2147483648.
在float以int示例遵循更复杂的规则.您的价值的相关部分是:
...如果浮点数不是无穷大,浮点值将四舍五入为整数值V,使用IEEE 754舍入零模式(§4.2.3)向零舍入.
... [if]值[is]太大(大幅度或正无穷大的正值),[then]第一步的结果是int或long类型的最大可表示值.
(但请参阅上面链接的规范部分以获取详细信息.)
因此,由于2147483648f舍入为2147483648且2147483648太大而无法放入int,因此使用int(2147483647)的最大值.
所以在longto int,它有点摆弄; 在floatto中int,它更具数学性.
在评论中你问过:
你知道为什么两个
(short) 32768并(short) 32768f评价-32768?我正在考虑后者来评估32767.
很好的问题,这就是我的"看到上面链接的细节部分的细节"来自.:-) (short) 32768f实际上,(short)(int)32768f:
在上面链接的规范部分中,在"将浮点数转换为整数类型T需要两个步骤:",它说
- 在第一步骤中,浮点数会被转换成一个
long,如果T是long,或一个int,如果T是byte,short,char,或int...
然后在第2步的第二个子弹中:
- *如果T是
byte,,char或者short,转换的结果是第一步结果的类型T(第5.1.3节)的缩小转换的结果.
所以在第一步中,32768f变成32768(一个int值),然后当然(short)32768是我们在long=> int上面看到的位斩波,给我们一个short值-32768.
Bat*_*eba 20
太好了!很高兴看到设计决策的效果以您的方式呈现.
2147483648l是一种long类型和规则的转换long这是过大,int是应用环绕成冶目标类型.(在引擎盖下,源类型的重要位被简单地丢弃.)
2147483648f是一种float类型,并且用于转换对于目标类型来说太大的规则是float为目标类型采用尽可能大的规则.引用是否在转换类型的MAX_INT处将Java整数类型基元强制转换为"上限"?
关于标准的好处是有很多可供选择的.