关于java代码中的位运算的使用

最近在查看java源码, 其实大量用到了位运算,在看到下面的代码时困惑了

 <span style="white-space:pre">	</span>long msb = 0;
        long lsb = 0;         
        for (int i=0; i<8; i++)
            msb = (msb << 8) | (data[i] & 0xff);
        for (int i=8; i<16; i++)
            lsb = (lsb << 8) | (data[i] & 0xff);
 

上面的java源码中为什么会用到data[i]&0xff来做处理, 而不是用过data[i]与变量msb做‘与运算’?

1.先说0xFF

java创建的数字,默认都给被赋予32位的内存空间,这个是java的内部机制,那么十六进制表示的oxff的所占用的空间用完全的十六进制表示应该为"0x0000 00FF";

2.再说位运算

首先得问题是:数字在进行位运算时,如果声明的数据类型少于32位,则会提升到32位数据后,进行运算;

java位运算包括‘与[&]’、‘或[|]’、‘非[~]’、‘异或[^]’; 和左移、右移[符号右移、无符号右移]

左移即数字的二进制格式向左移动, 低位补0;如“0010 1001” <<2 , 结果为1010 0100

右移即数字的二进制格式向右移动,这里分‘符号右移’和‘无符号右移’。

符号右移即向右移动,正数则高位补0, 负数则高位补1; 

如(41)‘0000 ...... 0010 1001’>>2, 结果为0000 1010(12)

 -23)‘1111 ...... 1110 1001’>>2, 结果为1111 1010(-6)

无符号右移即向右移动,高位补0;如(41)‘0000 ...... 0010 1001’>>2, 结果为0000 ...... 0000 1010

               -23)‘1111 ...... 1110 1001’>>>2, 结果为0011 ...... 0011 1010

与运算: 真真为真,否则为假; 如:0101 & 1001 =  0001

或运算: 假假为假,否则为真; 如:0101 | 1001 = 1101

非运算: 二进制位取反      如:~0101 = 1010

异或: 真假为真,否则为假    如: 1011^ 0101 = 1110


3.回到我们原来问题

"byte[i]"是指的一个byte类型数据, 假设为‘-6      二进制为: 1111 1010; 

0xFF的实际内存空间为0x0000 00FF,是32位的数据。二进制位:0000 ......1111 1111

在进行&运算的时候,首先会将byte[i]的实际内存提升为32位, 正数则高位补0,负数则高位补0。 如下:

1111 1111 1111 1111 1111 1111 1111 1010

& 0000 0000 0000 0000 0000 0000 1111 1111

------------------------------------------------------------------------------------

0000 0000 0000 0000 0000 0000 1111 1010

结果为最后8位(即FF表示的位数)为byte[i]的值, 前24位都为0;


至此,我们明白这里的byte[i]&0xFF的意义是“取到二进制的最后8位【即两个十六进制的值


 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值