数据的二进制表示
以下先以java中的byte类型为模板将(长度短,代码好写。。。)
byte b1 = (byte) 0b00000000;//0b表示后面的数据用二进制表示,0为八进制,0x为十六进制,十进制不带前缀
byte b2 = (byte) 0b10000000;
byte b3 = (byte) 0b11111111;
System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
//以上的输出结果为0、-128、-1
为何二进制与数据是这么对应的?个人理解是方便计算机进行运算。试想以下情况:
有一个数x的值为-128,我们使x加一变为-127,如果-128的二进制表示为0b11111111,那么-127应当为0b11111110,虽然值+1,但是二进制表示却是-1,底层不符合逻辑。所以逻辑一点,表面上既然+1,那底层最好也+1,所以-128用0b10000000来表示更合理,-127则相应的为0b10000001,底层的确比-128大1。
以这种方法表示,0b11111111则表示-1,而-1加一之后为0,二进制加一为0b100000000(8个0),因为byte长度为一个字节,即只有8bits,溢出的1被舍去,剩下为0b00000000,正好为0,符合-1+1=0。
数据类型转换
上面的东西看完之后,我们进入正题。
之前我正在用java来实现通信,期间需要将各种数据与byte类型进行转换,而在将byte型转成int型数据时发现了一件事情。以如下代码为例:
byte b = (byte) 0xff;//即255
System.out.println(b);
System.out.println((int) b);
System.out.println(b & 0xff);
System.out.println((int) (b & 0xff));
System.out.println(b | 0x00);
System.out.println((int) (b | 0x00));
三行输出分别为-1、-1、255、255、-1、-1
真是一件很令人头疼的事
我们先得出以下结论:
- 是否进行强制类型转换对结果没有影响
- 让byte型数据与0进行或("|")运算不会使输出结果发生改变(即以byte类型输出,值域为-128~127)
- 让byte型数据与0xff(相对于8bits的数据来说即各位全是1)进行与("&")运算,会以比byte值域更大的域来输出,输出的数据明显超过了byte的值域
现在我们来看看下面这种情况:
byte b = (byte) 0xff;
int num = (int) b;
System.out.println(num );
System.out.println(num & 0xff);
System.out.println(num & 0xffff);
System.out.println(num & 0xffffffff);
System.out.println(num | 0x00);
我们提前将byte类型转换成了int类型,输出结果如下:-1、255、65535、-1、-1
显然,num的二进制表示为0b111111111111111111111111(32个1)
我们又得出以下结论:
- 将byte型转换成int型时(可以拓展为短数据类型转换成长数据类型),会保持值不变(负数高位补1,正数高位补0)
- 与上面相反,将int型转换成byte型时(长变短),如果发生溢值,则会舍弃高位,保留低位
以上就是我进行的全部测试
但是这里还有一个问题没有解决,希望有大神能给我一些帮助:
为什么b & 0xff和b | 0x00的值不一样,理论上两者都不会使值发生变化
至此,我想讲的就讲完了,谢谢大家的阅读。