详解 & 0xff 的作用

原文链接:https://blog.csdn.net/i6223671/article/details/88924481

1.只是为了取得低八位

通常配合移位操作符>>使用

例如,有个数字 0x1234,如果只想将低8位写入到内存中
将 0x1234 & 0xff
0x1234 表示为二进制 00010010  00110100
0xff       表示为二进制 11111111
两个数做与操作,显然将0xff补充到16位,就是高位补0
此时0xff 为 0000000011111111
与操作 1&0 =0 1&1 =1 这样 0x1234只能保留低八位的数 0000000000110100 也就是 0x34

什么是低八位什么是高八位

1. 汇编中,为了表示一个整数类型,用两个字节来表示,即总共16位。高低8位是指16位的存储单元;
2. 汇编可以直接调用寄存器,比内存快,0~~7位为低八位,8~15位高八位,所以寄存器使用比较方便;
    比如00000000 00000000,前八个0的顺序是第15位到第8位,就是高八位后面的8个0就是低8位。
一个字节是8位,汇编中,为了表示一个整数类型,用两个字节来表示,即总共16位。同时在汇编中,一个整型是用二进制来表示的。例如 2 的二进制为10,4为100,3是11。但是用两个字节表示3为0000 0000 0000 0011,共16为,20是0000 0000 0001 0100.其中前0000 0000为高8位,后边0001 0100为低8位。两个字节的数据能表示正65535 - 负655
高低8位是指16位的存储单元,比如00000000 00000000
前八个0的顺序是第15位到第8位,就是高八位后面的8个0就是低8位
举个例子:1111000010101010,那么前面的11110000就是高八位,后面的10101010就是低八位。

2. 保证补码的一致性

    我们只关心二进制的机器数而不关注十进制的值,那么byte &0xff只是对其最低8位的复制,通常配合逻辑或 ‘’|’'使用,达到字节的拼接,但不保证其十进制真值不变。

public static void main(String[] args) {
		byte b = -127;//10000001   127二进制:01111111,-127:127取反加1,10000001 
		int a =  b;
		System.out.println(a);
		a =  b&0xff;
		System.out.println(a);
	}//输出结果-127,129

      b是8位的二进制数,在与上0xff(也就是 11111111),不就是其本身吗,输出在控制台结果为什么是129呢?
      首先计算机内的存储都是按照补码存储的,-127补码表示为 1000 0001,int a = b;将byte 类型提升为int时候,b的补码提升为 32位,补码的高位补1,也就是1111 1111 1111 1111 1111 1111 1000 0001。
负数的补码转为原码,符号位不变,其他位取反,在加1,正数的补码,反码都是本身
结果是 1000 0000 0000 0000 0000 0000 0111 1111表示为十进制 也是 -127,也就是 当 byte -> int 能保证十进制数不变,但是有些时候比如文件流转为byte数组时候,我们不是关心的是十进制数有没有变,而是补码有没有变,这时候需要&上0xff。
本例子中,将byte转为int 高24位必将补1,此时补码显然发生变化,在与上0xff,将高24重新置0,
这样能保证补码的一致性,当然由于符号位发生变化,表示的十进制数就会变了

原文地址:https://www.cnblogs.com/yangyuqing/p/12408405.html