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,
这样能保证补码的一致性, 当然由于符号位发生变化, 表示的十进制数就会变了
来源: http://www.bubuko.com/infodetail-3446494.html