【计算机组成原理】16进制0xff的作⽤
1、为什么⽤16进制
计算机硬件是0101⼆进制的,16进制刚好是2的倍数,更容易表达⼀个命令或者数据。
最早规定ASCII字符集采⽤的就是8bit(后期扩展了,但是基础单位还是8bit), 8bit⽤2个16进制直接就能表达出来,不管阅读还是存储都⽐其他进制要⽅便。
计算机中CPU运算也是遵照ASCII字符集,以16、32、64的这样的⽅式在发展,因此数据交换的时候16进制也显得更好。
为了统⼀规范,CPU、内存、硬盘我们看到都是采⽤的16进制计算。
2、⽬前16进制的⼀些⽤途
⽹络编程,数据交换的时候需要对字节进⾏解析都是⼀个byte⼀个byte的处理,1个byte可以⽤0xFF两个16进制来表达。
数据存储,存储到硬件中是0101的⽅式,存储到系统中的表达⽅式都是byte⽅式。
⼀些常⽤值的定义,⽐如:我们经常⽤到的html中color表达,就是⽤的16进制⽅式,4个16进制位可以表达好⼏百万的颜⾊。
3、&0xFF的作⽤
⾸先我们要都知道, &表⽰按位与,只有两个位同时为1,才能得到1,0x代表16进制数,0xff表⽰的数⼆进制1111 1111占⼀个字节。和其进
⾏&操作的数,最低8位,不会发⽣变化。
3.1 取得低⼋位
通常配合==移位操作符>>==使⽤。
例如:java socket通信中基于长度的成帧⽅法中,如果发送的信息长度⼩于65535字节,长度信息的字节定义为两个字节长度。这时候将两个字节长的长度信息,以Big-Endian的⽅式写到内存中
out.write((message.length>>8)&0xff);//右移8位,取⾼⼋位写⼊地址
out.write(message.length&0xff);//取低⼋位写⼊⾼地址中
例如,有个数字 0x1234,如果只想将低8位写⼊到内存中: 0x1234&0xff
0x1234 表⽰为⼆进制 0001 0010 0011 0100
0xff表⽰为⼆进制 1111 1111
两个数做与操作,显然将0xff补充到16位,就是⾼位补0。此时0xff为 0000 0000 1111 1111。
与操作 1&0 =0 、1&1 =1 这样 0x1234只能保留低⼋位的数 0000 0000 0011 0100 也就是 0x34
3.2 保证补码的⼀致性
我们只关⼼⼆进制的机器数⽽不关注⼗进制的值,那么byte &0xff只是对其最低8位的复制,通常配合逻辑或 |使⽤,达到字节的拼接,但不保证其⼗进制真值不变。
public static void main(String[] args){
byte b =-127;//10000001
int a =  b;
System.out.println(a);
a =  b&0xff;
System.out.println(a);
}//输出结果-127,129
using;
using;
class Program
{
static void Main(string[] args)
{
sbyte b =-127;
int a = b;
Console.WriteLine(a);
a =
b &0xff;writeline方法的作用
Console.WriteLine(a);
}
}
乍⼀看,b是8位的⼆进制数,在与上0xff(也就是 1111 1111),不就是其本⾝吗,输出在控制台结果为什么是129呢?
⾸先计算机内的存储都是按照补码存储的(如果不清楚补码可以去看这篇 ),-127补码表⽰为 1000 0001
int a = b;
将 byte 类型提升为 int 时候,b的补码提升为 32位,补码的⾼位补1,也就是:
1111 1111 1111 1111 1111 1111 1000 0001
负数的补码转为原码,符号位不变,其他位取反:
1000 0000 0000 0000 0000 0000 0111 1110
再加1,正数的补码,反码都是本⾝。
结果是
1000 0000 0000 0000 0000 0000 0111 1111,表⽰为⼗进制 也是 -127。
也就是 byte -> int 能保证⼗进制数不变,但是有些时候⽐如⽂件流转为byte数组时候,
我们不是关⼼的是⼗进制数有没有变,⽽是补码有没有变,这时候需要&上0xff
本例⼦中,将byte转为int,⾼的24位必将补1,此时补码显然发⽣变化,
1111 1111 1111 1111 1111 1111 1000 0001
再&上0xff,将⾼的24重新置0,
0xff:
0000 0000 0000 0000 0000 0000 1111 1111
结果是
0000 0000 0000 0000 0000 0000 1000 0001
这样能保证补码的⼀致性,当然由于符号位发⽣变化,表⽰的⼗进制数就会变了
和原来的补码 ⼀致,但是显然符号位变化了,表⽰的⼗进制数发⽣变化,变为129
总结
基本类型从⼩扩展到⼤的数据类型时候,正数因为符号位是0,⽆论如何都是补零扩展,但是负数补零扩展和补符号位1扩展完全不同,因此负数补符号位1扩展,保证⼗进制数不变
例如 byte>>>int -127⾃动按照补符号位1扩展,在⾼24位补符号位1,表⽰的⼗进制数不变
补零扩展,保证补码的⼀致性,但是表⽰的⼗进制发⽣变化。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。