首先说一下&,百度一下的说明
&是二进制“与”运算,参加运算的两个数的二进制按位进行运算,运算的规律是:
0 & 0=0
0 & 1=0
1 & 0=0
1 & 1=1
对于参加运算的数要换算为二进制进行运算,例如7 & 2的结果是2,过程如下:
7 & 2
=0111 & 0010
=0010
=2
即 &:按位与运算,两个当且仅当都为1的时候结果才为1,即
1&1==1
,
1&0==0&1==0&0==0
然后具体说一下在自己遇到时候的应用。在获取文件的MD5值得时候,使用&位运算处理数据,由于使用BigInteger获取digest.update的byte[]的时候,出现首位为0的时候消去。
后通过转化十六进制之间的转化之后,消除这个问题。中间遇到一段代码使用 & 的代码。
digest.update(buffer, 0, len); 方法
代码片段
StringBuilder result = new StringBuilder();
byte[] b = digest.digest();
for (int i = 0; i < b.length; i++) {
result.append(Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1));
}
return result.toString();
Integer.toString(
(b[i] & 0xff
)+
0x100
,
16
).substring(1);
解释:b[i]是一个byte,0x表示为十六进制,
0xff的十进制为15*16+15=255,0x100的十进制为1*16*16=256
Integer.toString(num,16);转成16进制,substring(1),起始位1, 结束为最后,来截取字符串。
即 转成二进制计算之后,又转成16进制,然后进行截取。
byte[i] & 0xff 的“与”运算,即与十六进制计算
&0xff目的应该是为了让原来的负数变成正数
byte[i] & 0xff与运算,如果与十六进制计算得到的byte[i]为负数,
计算机存储数据机制:正数存储的二进制原码,负数存储的是二进制的补码。
其中 补码是负数的绝对值反码加1。绝对值,取反,加1。
当 byte –> int ,byte一个字节即八位二进制,int4个字节即32位二进制, byte –> int 就是由8位变 32 位 高24位全部补1
这样前24位都是1。1111 1111 1111 1111 1111 1111 **** ****
而 0xFF的二进制表示就是:1111 1111。 转成int计算的时候 高24位补0:0000 0000 0000 0000 0000 0000 1111 1111
由& 的运算规则,只有1&1=1,那么
1111 1111 1111 11111111 1111 **** ****
&
0000 0000 0000 0000 0000 0000 1111 1111
=
0000 0000 0000 0000 0000 0000 #### ####
这样 byte[i] & 0Xff之后,可以使得前24位变0,称为正数。
所以需要& 0xFF 使得byte原来的负值变成正的