为什么在Java中左移以更改符号值 [英] Why left shifting in java changing the sign value

查看:166
本文介绍了为什么在Java中左移以更改符号值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究Java. 我想知道为什么Java会产生此输出. 我在这里共享代码.

I am working on java. I am wondering why java producing this output. I am sharing the code here.

public class vvn {

    public static void main(String[] args)
    {
        byte [] arr = new byte[4];
        arr[0] = (byte)157;
        arr[1] = 1;
        arr[2] = 0;
        arr[3] = 0;
        System.out.format("read 0x%x 0x%x 0x%x 0x%x \n",arr[3],arr[2],arr[1],arr[0]);
        int v = (arr[0] | (arr[1] << 8) | (arr[2] << 16) | (arr[3] << 24));
        System.out.format("read 0x%x\n",v);

    }

}

我得到的输出为

read 0x0 0x0 0x1 0x9d 
read 0xffffff9d

我希望输出应为0x0000019d

I expected the output should be 0x0000019d

推荐答案

您正在从字节(带符号的8位)转换为整数(带符号的32位).最高位(最左边的一位)带有符号(请参见二进制补码).

You are converting from byte (signed 8 bits) to integer (signed 32 bits). The most significant bit (the leftmost one) holds the sign (see two's complement).

您的157是二进制的10011101.由于您将此值分配给带符号的字节(java没有无符号的字节),因此实际上这是一个负数-99.

Your 157 is 10011101 in binary. Since you assign this value to a signed byte (java has no unsigned byte), this is in fact a negative number, -99.

现在,当您从字节转换为整数时,将保留该值.在负数的情况下,这意味着将所有位都设置在左侧以保留有符号性.在您的情况下,10011101变为11111111 11111111 11111111 10011101.

Now when you convert from byte to int, the value is preserved. In case of negative numbers, this means setting all the bits to the left to preserve the signedness. In your case, 10011101 becomes 11111111 11111111 11111111 10011101.

无论如何,在Java中使用无符号字节是一场噩梦.基本上,您需要使用0xff屏蔽所有内容(以切断左侧的对象"),如下所示:

Anyway, working with unsigned bytes in java is a nightmare. Basically, you need to mask everything with 0xff (to cut off the 'ones to the left') like this:

int v = ((arr[0] & 0xff) |
    ((arr[1] & 0xff) << 8) |
    ((arr[2] & 0xff) << 16) |
    ((arr[3] & 0xff) << 24));

美丽,不是吗?

更新1:另外,您可能对Guava的

Update 1: Also, you may be interested in Guava's UnsignedBytes...

更新2: Java 8字节具有toUnsignedInt()和toUnsignedLong()方法.您的计算结果将变为:

Update 2: Java 8 Byte has toUnsignedInt() and toUnsignedLong() methods. Your calculation thus becomes:

int v = (Byte.toUnsignedInt(arr[0]) |
    (Byte.toUnsignedInt(arr[1]) << 8) |
    (Byte.toUnsignedInt(arr[2]) << 16) |
    (Byte.toUnsignedInt(arr[3]) << 24));

这篇关于为什么在Java中左移以更改符号值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆