Java无符号数据类型处理

1、无符号与有符号对比:

​ 下面以Byte字节类型举例:

​ 有符号类型数据 符号位 数据位

1 1111111

​ 无符号类型数据 数据位
​ 11111111

​ 上述,无符号数据类型,二进制表示为11111111,十进制也就是255;如果是有符号数据,十进制则是 -1,这里为什么不是 -127呢?这里涉及到一个原码,反码,补码的问题。

​ 因为计算机存储的是以补码方式存储,其中原码、反码与补码关系如下:
​ (1)正数的补码 == 反码 == 原码
​ (2.1)负数的补码 == 反码(原码符号位不变,数据位取反) + 1
​ (2.2)负数的补码 == 原码,符号位不变,低位到高位,出现首个1比特位的高位全部取反(其实和2.1是一样)

​ 因此,在有符号数据中,补码1111 1111,原码则为1000 0001,也就是十进制 -1。

2、无符号转有符号:

​ 在 Java中并没有无符号数据类型,在跨平台通信的时候,就可能涉及无符号与有符号之间的转换。当然,就算不进行有无符号的转换,数据还是对的,但是在处理业务逻辑的时候,同一个数据却代表了不同含义。如上方,1111 1111,无符号平台表示的是十进制255,而 Java平台则表示 -1。

​ 一个byte字节8位,无符号取值范围 0 ~ 255,有符号取值范围 -128 ~ 127(1000 0000为-128),所以用 java的byte去存储无符号的byte,进行业务处理显然是不正确的。因此需要将无符号的byte存储为 java的 int类型。也就是转换成更大范围的数据存储。

当然,无符号int 也是类似,转化成 long存储使用。

/**
 * 无符号 byte类型转 int
 */
public static Integer byteToUnsignedInt(byte x) {
    return ((int) x) & 0xff;
}

/**
 * 无符号 short类型转 int
 */
public static int shortToUnsignedInt(short x) {
    return ((int) x) & 0xffff;
}

/**
 * 无符号 int类型转 long
 */
public static long intToUnsignedLong(int x) {
    return ((long) x) & 0xffffffffL;
}

例子:

byte num = -0b1111111;    // -127   补码存储 1000 0001
System.out.println(JavaUnsignedDataUtil.byteToUnsignedInt(num));    // 忽略符号位
// 输出打印输出 129,存储在 int当中

3、有符号转无符号:

​ 这里具体转换还需要看具体规则,如果按照 2中的转换规则,这里将有符号转回无符号则用Java的强制类型转换即可。

​ 例如:(byte)int

你可能感兴趣的:(Java无符号数据类型处理)