管理范围缩小到int的规则
请注意我不是要寻找代码来强制转换或缩小double到int。
根据JLS – $ 5.1.3缩小原始转换
将有符号整数缩小到整数类型T只会丢弃除n个最低位之外的所有位,其中n是用于表示类型T的位数。
因此,当我尝试将260(二进制表示为100000100
)缩小100000100
一个字节时,结果为4,因为最低的8位是00000100
,这是一个小数4或一个长值4294967296L(二进制表示100000000000000000000000000000000
)到一个字节然后结果是0。
现在,为什么我想知道缩小规则从double到int,byte等的规则是当我缩小一个double
值4294967296.0
然后结果是2147483647
但是当我缩小一个长4294967296L
值然后结果为0
。
我已经理解了对int,byte等的长时间缩小(丢弃除n个最低位之外的所有位)但我想知道在双倍缩小的情况下会发生什么。
我已经理解了对int,byte等的长时间缩小(丢弃除n个最低位之外的所有位)但我想知道在双倍缩小的情况下会发生什么。
……我想了解原因和部分原因。
-
JLS( JLS 5.1.3 )指定结果。 简化版(对于
int
)是:- NaN变为零
- Inf成为“max-int”或“min-int”
- 除此以外:
- 向零舍入以获得数学整数
- 如果舍入的数字对于
int
来说太大,则结果变为“min-int”或“max-int”
-
“如何”是特定于实现的。 有关如何实现它的示例,请查看Hotspot源代码(OpenJDK版本)或获取JIT编译器以转储一些本机代码供您查看。 (我想原生代码映射使用单个指令来进行实际转换….但我没有检查过。)
-
“为什么”是不可知的……除非你能问一位原始的Java设计师/规范作者。 一个看似合理的解释是:
- 这很容易理解
- 它与C / C ++一致,
- 它可以在通用硬件平台上高效实现
- 它比设计师考虑的(假设的)替代品更好。
(例如,抛出NaN,Inf的exception,超出范围将与其他原始转换不一致,并且实现起来可能更昂贵。)
将double转换为整数时,结果为Integer.MAX_VALUE,并且该值超出整数范围。 Integer.MAX_VALUE是2 ^ 31 – 1。
当您使用双精度值4294967296.0开始时,它大于最大长值2147483647,因此应用以下规则(从您引用的页面): 值必须太大(大幅度或正无穷大的正值) ),第一步的结果是int或long类型的最大可表示值,你得到0x7FFFFFF = 2147483647
但是当你尝试转换4294967296L = 0x100000000时,你从一个整数类型开始,所以规则是: 将有符号整数缩小转换为整数类型T只是丢弃除n个最低位之外的所有位,所以如果n小于32 (8个字节)你得到一个0。