【问题标题】:Narrowing from int to short [duplicate]从int缩小到short [重复]
【发布时间】:2015-10-21 23:03:34
【问题描述】:

我正在缩小并检查了以下代码:-

int i = 131072;
short s = (short)i;
System.out.println(s); //giving 0

这个缩小正在输出0。我无法理解背后的逻辑。

【问题讨论】:

  • 您的预期输出到底是什么?对我来说,预期的输出是0
  • 这有帮助吗? System.out.println(Integer.toBinaryString(i))
  • @MarkoTopolnik 不期待什么,只是想知道这是如何工作的
  • 参见docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.3 - “有符号整数到整数类型 T 的窄化转换只会丢弃除 n 个最低位之外的所有位,其中 n 是用于表示类型 T 的位数。”
  • 如有疑问,请查阅规范...

标签: java


【解决方案1】:

131072 int 是二进制的00000000 00000010 00000000 00000000

当您将其大小写为 short 时,只剩下最低 16 位 - 00000000 00000000

【讨论】:

    【解决方案2】:

    当您将一个基元转换为一个较小的基元时,最高位会被丢弃。

    以另一种方式编写,您可以看到正在发生的事情。

    int i = 0x20000;
    short s = (short) (i & 0xFFFF);
    

    注意:整数的低 16 位全为零,所以答案是 0。

    由于二进制转换为(短)只保留低 16 位。

    00000000 00000010 (00000000 00000000)
    

    如果您要转换更长的数字,则在每种情况下仍会采用较低的位。注意:& 在每种情况下都是多余的,只是为了帮助清晰。

    long l = 0x0FEDCBA987654321L;
    
    // i = 0x87654321
    int i = (int) (l & 0xFFFFFFFFL);
    
    // c = \u4321
    char c = (char) (l & 0xFFFF);
    
    // s = 0x4321
    short s = (short) (l & 0xFFFF);
    
    // b = 0x21
    byte b = (byte) (l & 0xFF);
    

    【讨论】:

    • 这个答案似乎把行为背后的概念解释得最清楚最透彻了。
    • 感谢您解释该行为。赞赏。谢谢:)
    • @AnkitNigam 我已经为所有整数类型添加了示例。
    • @AnkitNigam hexidecimal 是一种常用于二进制数据的表示,因为它更短且易于翻译。它由 16 个可能的数字 0 到 9 和 A - F 组成。F 在二进制中是 1111,所以当你看到 FF 时,它表示 8 x 1。 FFFF 是 16 x 1。当您将& 与二进制一起使用时,所有相同的位都必须为1 才能产生1 结果,因此当您使用& 0xFF 时,您只保留设置的位,即低8 位。
    • @AnkitNigam Java 使用签名的intshortbyte。它使用二补码,这意味着如果最高位为1,则该数字为负数。因此,当最高位为 1 时,您应该期待一个负数。byteshortintlongfloatdouble 都是如此。注意:char 是无符号的,所以数字始终为非负数。
    【解决方案3】:

    原始值(intshort、...)存储为二进制值。 int 使用的位数比 short 多。当您尝试向下转换时,您正在削减会截断(并可能破坏)价值的位。

    【讨论】:

      【解决方案4】:

      这不是向下转换(指对象),而是缩小转换或截断。当您执行这样的转换时,您只需将int 的两个最低有效字节复制到您的short。如果小于 215 的整数,您只需忽略包含零的字节,这样就可以了。

      但是,这里不是这种情况。如果您检查131072 的二进制表示,您会看到它是100000000000000000。所以,最不重要的两个字节显然是0,这正是你得到的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-14
        • 2014-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-12
        • 2015-12-25
        相关资源
        最近更新 更多