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
网友评论