java byte & 0xFF 的奇妙作用

在编程语言中,存在不同的数据类型,C#和JAVA共同的拥有byte这种类型,不过同样叫byte,存储的时候却有细微差别的。JAVA语言中,是没有unsigned,每个数据类型的高位都是符号位,0表示整数,1表示负数。当超过当前数据类型的数字时,计算机会采用一种补码的方式来存储。

同样是128,java中的byte占一个字节空间,最高位是符号位,剩余7位能表示0-127,加上符号位的正负,就是-127至+127。byte整数无法存储,转为补码,就用负零表示-128(即原码1000,0000)。(计算机转补码后存储)

比较有意思的是,当byte转为short,int这种较大范围,能够存储128的数值时,打印出来还是-128.

这里涉及到小类型转大类型时的补位操作。

既然值没有改变,可以猜测,高位补位扩展转为大类型时是补零,高位保留了原有符号。

128  ->byte = -128   二进制  1000 0000    ->short 二进制 1000 0000 1000 0000   = -128

->int  二进制 1000 0000 0000 0000 0000 0000 1000 0000  = -128 

那要怎样才能保证byte存储的128,转成int,short的值也应该是128了?java源码这样写道:

我们发现了一个有趣的地方,byte & 0xFF。根据计算机常识

1000 0000 0000 0000 0000 0000 1000 0000 & 1111 1111 = 0000 0000 0000 0000 0000 0000 1000 0000 = 128

这里0xFF是强制去掉了补位操作的高位的符号位。

那如果我们本来就是存进去的就是一个负数呢?转成int的时候又会怎么样?

-2 & 0xFF发生了什么?

总所周知,计算机保存负数是保存数的反码。

-2   源码  1000 0010  反码 1111 1101 补码 1111 1110

-2 & 0xFF 1111 1110 & 1111 1111  = 1111 1110 = 254

如果不&上0xFF自动扩展,保留符号

(byte)-2 1111 1110  转int  1111 1111 1111 1111 1111 1111 0111 1110 = -2

所以这里存在的问题是原本是负数,& 0xFF后不再是原数,原本是正数的,必须& 0xFF。

猜你喜欢

转载自blog.csdn.net/ido1ok/article/details/85235955
今日推荐