16进制的作用以及&0xff详解

十年热恋 提交于 2019-12-26 16:08:52

1、概述

在看源码的时候,发现有好些地方使用了16进制,在此记录一下。

2、为什么用16进制

  1. 计算机硬件是0101二进制的,16进制刚好是2的倍数,更容易表达一个命令或者数据
  2. 最早规定ASCII字符集采用的就是8bit(后期扩展了,但是基础单位还是8bit), 8bit用2个16进制直接就能表达出来,不管阅读还是存储都比其他进制要方便
  3. 计算机中CPU运算也是遵照ASCII字符集,以16、32、64的这样的方式在发展,因此数据交换的时候16进制也显得更好
  4. 为了统一规范,CPU、内存、硬盘我们看到都是采用的16进制计算

3、目前16进制的一些用途

  1. 网络编程,数据交换的时候需要对字节进行解析都是一个byte一个byte的处理,1个byte可以用0xFF两个16进制来表达
  2. 数据存储,存储到硬件中是0101的方式,存储到系统中的表达方式都是byte方式
  3. 一些常用值的定义,比如:我们经常用到的html中color表达,就是用的16进制方式,4个16进制位可以表达好几百万的颜色

4、&0xFF的作用

一下内容来自,:link

首先我们要都知道, &表示按位与,只有两个位同时为1,才能得到1, 0x代表16进制数,0xff表示的数二进制1111 1111 占一个字节.和其进行&操作的数,最低8位,不会发生变化.

&0xff都有哪些应用:

4.1 只是为了取得低八位

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

例如:java socket通信中基于长度的成帧方法中,如果发送的信息长度小于65535字节,长度信息的字节

定义为两个字节长度。这时候将两个字节长的长度信息,以Big-Endian的方式写到内存中

out.write((message.length>>8)&0xff);//取高八位写入地址
out.write(message.length&0xff);//取低八位写入高地址中

例如,有个数字 0x1234,如果只想将低8位写入到内存中 0x1234&0xff
0x1234 表示为二进制 0001001000110100

0xff 表示为二进制 11111111

两个数做与操作,显然将0xff补充到16位,就是高位补0

此时0xff 为 0000000011111111

与操作 1&0 =0 1&1 =1 这样 0x1234只能保留低八位的数 0000000000110100 也就是 0x34

4.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

乍一看,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,

这样能保证补码的一致性,当然由于符号位发生变化,表示的十进制数就会变了

1111 1111 1111 1111 1111 1111 1000 0001 

&

0000 0000 0000 0000 0000 0000 1111 1111

结果是

0000 0000 0000 0000 0000 0000 1000 0001

和原来的补码 一致,但是显然符号位变化了,表示的十进制数发生变化,变为129

4.3 总结

java中基本类型从小扩展到大的数据类型时候,正数因为符号位是0,无论如何都是补零扩展,但是负数补零扩展和补符号位扩展完全不同,

负数补符号位扩展,保证十进制数不变

例如 byte>>>int -127自动按照补符号位扩展,在高24位补符号位1,表示的十进制数不变

补零扩展,保证补码的一致性,但是表示的十进制发生变化

例如,本例中byte提升为int,&0xff的操作

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!