管理范围缩小到int的规则

请注意我不是要寻找代码来强制转换或缩小double到int。

根据JLS – $ 5.1.3缩小原始转换

将有符号整数缩小到整数类型T只会丢弃除n个最低位之外的所有位,其中n是用于表示类型T的位数。

因此,当我尝试将260(二进制表示为100000100 )缩小100000100一个字节时,结果为4,因为最低的8位是00000100 ,这是一个小数4或一个长值4294967296L(二进制表示100000000000000000000000000000000 )到一个字节然后结果是0。

现在,为什么我想知道缩小规则从double到int,byte等的规则是当我缩小一个double4294967296.0然后结果是2147483647但是当我缩小一个长4294967296L值然后结果为0

我已经理解了对int,byte等的长时间缩小(丢弃除n个最低位之外的所有位)但我想知道在双倍缩小的情况下会发生什么。

我已经理解了对int,byte等的长时间缩小(丢弃除n个最低位之外的所有位)但我想知道在双倍缩小的情况下会发生什么。

……我想了解原因和部分原因。

  1. JLS( JLS 5.1.3 )指定结果。 简化版(对于int )是:

    • NaN变为零
    • Inf成为“max-int”或“min-int”
    • 除此以外:
      • 向零舍入以获得数学整数
      • 如果舍入的数字对于int来说太大,则结果变为“min-int”或“max-int”
  2. “如何”是特定于实现的。 有关如何实现它的示例,请查看Hotspot源代码(OpenJDK版本)或获取JIT编译器以转储一些本机代码供您查看。 (我想原生代码映射使用单个指令来进行实际转换….但我没有检查过。)

  3. “为什么”是不可知的……除非你能问一位原始的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。