&0xFF、~运算符

java中byte转换成int时,如果我们期望得到的int是允许>=128的无符号数,或者int需要再转换成16进制字符串,则byte需要与0xff进行与运算

int是32位的,而byte是8位的,计算机存储和通信使用的是补码

我们平时觉得编程中二进制与我们的直观认知比较一致,是因为我们接触的大部分场景是无符号正数,此时的补码与原码一致,遇到负数的情况,补码与原码差异较大,就需要好好理解,因为会与直观认知比较不一致正数的原码、反码、补码都是本身,1是00000001

负数的反码为原码除符号位外每一位取反,补码为反码+1

有符号场景下,负数-1的原码是10000001(第一个1是符号位),反码是11111110(除符号位外都取反),补码是11111111,16进制字符串为0xff

无符号场景下,正数129的原码是10000001(第一个1不是符号位),反码和补码都是10000001,16进制字符串为0x81

无符号场景下,>=128的无符号数:

0x81,期望结果是正数129,原码是10000001。由于是无符号场景,所以计算机初始存储的是10000001。在强制类型转换为int时,会补位到32位,由于java默认是有符号数,并且符号位是1,所以补1,变为11111111111111111111111110000001(反码为11111111111111111111111110000000,原码为10000000000000000000000001111111),如果不与0xff进行与运算,输出的是-127。与0xff进行与运算,由于系统认为0xff就是int,所以在与的时候,会先将byte强制类型转换为int再与运算,也就是说运算的实质是补码运算:11111111111111111111111110000001&11111111=00000000000000000000000010000001,计算机认为是正数,于是反码和原码均为00000000000000000000000010000001,于是输出129。

有符号场景下,负数需要转换成16进制字符串:

负数-1,期望结果是0xff,原码是10000001。由于是负数,于是反码是11111110,补码是11111111,也就是说计算机初始存储的是11111111,与期望结果一致。在强制类型转换为int时,会补位到32位,由于java默认是有符号数,并且符号位是1,所以补1,变为11111111111111111111111111111111(反码为11111111111111111111111111111110,原码为10000000000000000000000000000001),如果不与0xff进行与运算,输出的是0xffffffff。与0xff进行与运算,由于系统认为0xff就是int,所以在与的时候,会先将byte强制类型转换为int再与运算,也就是说运算的实质是补码运算:11111111111111111111111111111111&11111111=00000000000000000000000011111111,于是输出0xff。

~运算符,也就是按位取反,因为计算式存储的是补码,所以取反其实也是对补码取

~9的结果:

9的二进制为0000 1001,9的原码为0000 1001,9的反码为0000 1001,9的补码为0000 1001,按位取反后的补码为1111 0110,再计算按位取反后的原码,反码为1111 0101,原码为1000 1010,即-10

~-9的结果:

-9的二级制为1000 1001,-9的原码为1000 1001,-9的反码为1111 0110,-9的补码为1111 0111,按位取反后的补码为0000 1000,再计算按位取反后的原码,反码为0000 1000,原码为0000 1000,即8

参考文献:

https://blog.csdn.net/mx0418/article/details/82894579

https://blog.csdn.net/smilecall/article/details/42454471

https://www.cnblogs.com/welen/articles/4825851.html

https://www.cnblogs.com/yeahwell/p/5533571.html

https://www.cnblogs.com/yongdaimi/p/5945114.html

https://blog.csdn.net/qq_16855077/article/details/84025059

Share

You may also like...

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注