【问题标题】:How are integers cast to bytes in Java?Java中的整数如何转换为字节?
【发布时间】:2011-01-28 08:18:52
【问题描述】:

我知道 Java 不允许无符号类型,所以我想知道它是如何将整数转换为字节的。假设我有一个值为 255 的整数 a 并将整数转换为一个字节。该值是否以字节 11111111 表示?换句话说,该值是更多地被视为一个有符号的 8 位整数,还是直接复制整数的最后 8 位?

【问题讨论】:

    标签: java int byte casting


    【解决方案1】:

    以下片段将 int 转换为 byte。如果整数的值大于一个字节的范围,它将以模(整数除以的余数)字节的范围缩小。

    int a;
    byte b;
    // …
    b = (byte) a;
    

    【讨论】:

      【解决方案2】:

      根据我的理解,你的意思是

      Integer i=new Integer(2);
      byte b=i;   //will not work 
      
      final int i=2;
      byte b=i;   //fine 
      

      终于

      Byte b=new Byte(2);
      int a=b;   //fine
      

      【讨论】:

        【解决方案3】:

        字节为 8 位。 8 位可以表示 256 个数字。(2 提高到 8=256)
        现在第一位用于符号。 [如果为正则第一位=0,如果为负则第一位=1]
        假设您要将整数 1099 转换为字节。只需将 1099 除以 256。余数是 int
        示例
        的字节表示 1099/256 => 余数 = 75
        -1099/256 =>余数=-75
        2049/256 => 余数= 1
        原因?看这张图http://i.stack.imgur.com/FYwqr.png

        【讨论】:

          【解决方案4】:
          for (int i=0; i <= 255; i++) {
              byte b = (byte) i;    // cast int values 0 to 255 to corresponding byte values 
              int neg = b;     // neg will take on values 0..127, -128, -127, ..., -1
              int pos = (int) (b & 0xFF);  // pos will take on values 0..255
          }
          

          将包含大于 127 的值(即值 0x80 到 0xFF)的字节转换为 int 会导致字节值的高位(即位 0x80)的符号扩展。要删除“额外”的一位,请使用 x & 0xFF;这会强制高于 0x80 的位(即位 0x100、0x200、0x400,...)为零,但保持低 8 位不变。

          你也可以写这些;它们都是等价的: int pos = ((int) b) & 0xFF; // 先将 b 转换为 int,然后去掉高位 int pos = b & 0xFF; // 作为 int 算术完成——不需要强制转换

          在进行算术运算时,Java 会自动将大小(以位数为单位)小于 int 的整数类型“提升”为 int 值。这样做是为了提供更具确定性的结果(与 C 相比,C 的规范限制较少)。

          你可能想看看this question on casting a 'short'.

          【讨论】:

            【解决方案5】:

            只是对所说内容的想法:在转换为具有 0xFF 的字节时(对于整数),请始终屏蔽您的整数。 (假设 myInt 被赋值为 0 到 255)。

            例如

            char myByte = (char)(myInt & 0xFF);
            

            为什么?如果 myInt 大于 255,则仅类型转换为 byte 会返回您不想要的负值(2 的补码)。

            【讨论】:

            • char 在java中是两个字节。
            • char 在 java 中是 16 位。如果您将示例更改为byte,它也不起作用,仍然可能产生负值。您可以使用 0x7F 进行屏蔽,但是负值将无法正确转换。确保您不会遇到问题的好方法可能是assert -128 &lt;= myInt &amp;&amp; myInt &lt;= 127;
            • @Philippe,谢谢。我工作很晚,所以我写得太快了,但是,short 在 java 中有多大?
            • short 是有符号的两字节类型,而char 是无符号的两字节类型。
            • 我明白你想说什么,总的来说这是个好建议。在我的具体情况下,我已经知道 int 中的值小于 255。
            【解决方案6】:

            这称为narrowing primitive conversion。根据规范:

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

            所以这是您列出的第二个选项(直接复制最后 8 位)。

            我不确定你是否知道有符号整数值是如何表示的,所以为了安全起见,我会指出 two's complement 系统中的字节值 1111 1111 等于 -1 (Java 使用的)。

            【讨论】:

            • 是的,我知道二进制补码。所以,澄清一下,如果我有一个值为 -1 的 long 类型,并且我将它转换为 int,结果将是 65535?顺便感谢您快速详细的回复。
            • @helixed:不,它也会是-1,因为它也是全1。较小类型范围内的任何内容都将转换为等效值。
            • 哦,等等,我明白了。由于 2 的补码,较小类型范围内的任何负值无论如何都将用 1(二进制)填充,因此结果将始终保留其符号。再次感谢。
            • @helixed:是的,没错。一旦超出较小类型的范围,它实际上与溢出或下溢相同。
            【解决方案7】:
            int i = 255;
            
            byte b = (byte)i;
            

            所以十六进制的值为0xFF,但十进制值为-1。

            int i = 0xff00;
            
            byte b = (byte)i;
            

            b 的值现在是 0x00。这表明 java 取整数的最后一个字节。 IE。最后 8 位,但这是有符号的。

            【讨论】:

              【解决方案8】:

              还是直接复制最后一个 8位整数

              是的,这就是这种铸造的工作方式

              【讨论】:

                猜你喜欢
                • 2010-12-28
                • 2015-10-18
                • 2016-01-10
                • 1970-01-01
                • 2019-09-15
                • 2016-02-06
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多