ps:其实这篇文章我是想不出叫什么名字了。。。。。。
事情是这样的,最近用java把一个4 byte转成int,于是写出了这种代码:
int dataSize = ((dataSizeArray[3]) | (dataSizeArray[2]) << 8 | (dataSizeArray[1]) << 16 | (dataSizeArray[0]) << 24);
这段代码的问题是什么,上面的过程byte被隐式转换成int再移位求或,byte[0] = 0x81 (-127),我们本意是转成这样0x00000081,而实际上由于负数用补码表示,结果是这样0xffffff81,这串1和其它byte做或操作可想而知,所以实际应用的时候我们要想办法去掉补码的部分的影响,保留我们想要的8bit,其它bit变成全0,那么就应该 & 0xff,正确的版本:
int dataSize = ((dataSizeArray[3] & 0xff) | (dataSizeArray[2] & 0xff) << 8 | (dataSizeArray[1] & 0xff) << 16 | (dataSizeArray[0] & 0xff) << 24);
为了直观的演示我们用c语言演示一下:
$ cat testBit.c
#include <stdio.h>
int main(int argc, char** argv) {
unsigned char u = -127;
char c = -127;
printf("%d %d\n", u, c);
printf("%X %X\n", u, c);
printf("%d %d\n", u, u & 0xFF);
printf("%d %d\n", c, c & 0xFF);
return 0;
}
$ ./testBit
129 -127
81 FFFFFF81
129 129
-127 129