移位操作符注意点

移位操作符注意点Java 中的“位”操作符计算机中最小的单位是“位”(bit)。位的取值只能是 0 或 1。Java 中有“两种”直接对“位”进行运算的操作符:按位操作符、移位操作符。注意:Java 中的位操作符只用于 int 类型

Java 中的“位”操作符   计算机中最小的单位是“位”(bit)。位的取值只能是 0 或 1。   Java 中有“两种”直接对“位”进行运算的操作符:按位操作符、移位操作符。   注意:Java 中的位操作符只用于 int 类型的数据。byte、short、char 类型的数据也可以使用位操作符,但在操作之前会被自动转为 int 类型,返回的结果也是 int 类型。(int 为四字节,byte 为一字节,short、char 为 二字节)   按位操作符   按位操作符有四个:按位与 按位或 按位异或 按位取反   按位与:两个输入位都为 1 ,得到一个输出位 1,否则得到一个输出位 0。   1&1=1,1&0=0,0&1=0,0&0=0。   按位或:两个输入位只要有一个为 1 ,得到一个输出位 1,否则得到一个输出位 0。   1|1=1,1|0=1,0|1=1,0|0=0。   按位异或:两个输出位一个为 0 一个为 1,得到一个输出位 1,否则得到一个输出为 0。按位异或也可以理解为“不进位的按位相加”。   1^1=0,1^0=1,0^1=1,0^0=0。   自己与自己按位异或等于 0;   与 0 按位异或等于自身;   按位异或满足交换律:a^b = b^a。(以“不进位的按位相加”更好理解。)   按位取反:一操作符,输入位为 0,输出位为 1,或,输入位为 1,输出位为 0。   ~1=0,~0=1。   在实际代码中, 会输出 -2, 会输出 -1。这是因为:   x + (~x) = 0b1111 1111,   x + (~x) + 1 = 0b0000 0000 = 0,   因此,~x = -x – 1。   以 1 为例,int 类型的 1 的二进制为 0b0000 0001,取反后为 0b1111 1110,这正是 int 类型的 -2 的二进制;   以 0 为例,int 类型的 0 的二进制为 0b0000 0000,取反后为 0b1111 1111,这正是 int 类型的 -1 的二进制。计算机内部用补码来表示负数,即,将负数的绝对值的二进制按位取反再加一。以一个字节为例,2 的二进制为 0b00000010,则 -2 = 0 – 2 = 0b00000000 – 0b00000010 = 0b00000001 + 0b – 0b00000010 = 0b00000001 + 0b = 0b,即 -2 的二进制为 0b。 正负数相加时,补码的优势就显现出来了:2+(-2) = 0b00000010+0b = 0b00000000 = 0。   Java 支持 、 和 。(由于 ~ 为一操作符,所以不支持 。)   移位操作符   移位操作符有三个:左移位操作符 “有符号”右移位操作符 “无符号”右移位操作符   左移位操作符:向左移位,低位补 0。   以一个字节为例:   2<<1 = 0b00000010<<1 = 0b00000100 = 4;   2<<2 = 0b00000010<<2 = 0b00001000 = 8;   -(2<<1) = -(0b00000010<<1) = -(0b00000100) = -4;   (-2)<<1= (0b)<<1 = 0b = -4;   左移一位相当于乘以 2,左移两位相当于乘以 4,以此类推。   注意:当数字较大,或左移位数较多时,要特别当心。例如,(2^31-1)<<1 = -2,这是因为 Java 中的 int 类型占用四个字节,(2^31-1) 表示为 0b0111……1111,向左移动一位后,变为了 0b111……1110,与 -2 的表示相同,Java 将其识别为了-2。(无符号类型 char 不会遇到这种情况)   “有符号”右移位操作符:向左移位,若为正数,高位补 0,若为负数,高位补 1。   以一个字节为例:   2>>1 = 0b00000010>>1 = 0b00000001 = 1;   2>>2 = 0b00000010>>2 = 0b00000000 = 0;   -(2>>1) = -(0b00000010>>1) = -(0b00000001) = -1;   (-2)>>1= (0b)>>1 = 0b = -1;   “有符号”右移一位相当于除以 2(向下取整),“有符号”右移两位相当于除以 4(向下取整),以此类推。   “除以 4,向下取整”与“除以 2,向下取整,再除以 2,再向下取整”两者完全等价。   正数经过有限次的“有符号”右移后,最终都将变为 0;负数经过有限次的“有符号”右移后,最终都将变为 -1。   “无符号”右移位操作符:向左移位,高位补 0。   当两个很大的正数相加,且相加后最高位等于一,求它俩的平均数(除二取整),这时候不能用 >>(因为右移后最高位会补一),而应该用 >>>(最高位补零)。   Java 支持 、 和 。   位操作符的常见用法   1 交换整数 a 和 b 的值的方法:   2 对一个整数的二进制“重复两次”按位取反后加一,得到其本身:~(~a+1)+1 = a+(~1)+1 = a。   3 :一个整数与自己的相反数按位与。   作用:二进制下最后出现(最右侧)的 1 保持不变,其余都置为 0,也即提取出二进制下最右侧的 1。例如:   原数:0b   相反数就是数按位取反后再加一。   取反:0b0   加一:0b0   按位与:   
\frac{0b10101100 }{0b01010100} = 0b00000100     证明:   如果 x 是奇数,那二进制下最后一位肯定是 1,如果用 a 表示一串任意的 0110…1001,那 x 的二进制可以表示为 a1,-x 的二进制可以表示为 ~(a1)+1=(~a)0+1=(~a)1,于是 x&(-x)=a1&(~a)1=00…001,得证。   如果 x 是偶数,那 x 的二进制可以表示为 a100…00,-x 的二进制可以表示为 ~(a100…00)+1=~(a)011…11+1=~(a)100…00,于是 x&(-x)=a100…00&(~a)100…00=00…00100…00,得证。   4 :一个整数减一,然后与自身按位与。   作用:二进制下最后出现(最右侧)的 1 置为 0,其余保持不变。   证明:   如果 x 是奇数,那二进制下最后一位肯定是 1,如果用 a 表示一串任意的 0110…1001,那 x 的二进制可以表示为 a1,x-1 的二进制可以表示为 a0,于是 x&(x-1)=a1&a0=a0,得证。   如果 x 是偶数,那 x 的二进制可以表示为 a100…00,x-1 的二进制可以表示为 a011…11,于是 x&(x-1)=a100…00&a011…11=a000…00,得证。   用途:判断一个正整数是否为 2 的 n 次方。   1 的二进制 1;   2 的二进制 10;   4 的二进制 100;   8 的二进制 1000;   2 的 n 次方有一个共同点,它们的二进制最左侧为 1,其它都为 0。如果 x&(x-1)=0,那它必是2 的 n 次方。   用途:求一个正整数对应二进制数中包含的 1 的个数。   每进行一次 x&(x-1),右侧就少一个 1。   其它   Python 中也有相同的“位”操作符:按位与 按位或 按位异或 按位取反 左移位操作符 “有符号”右移位操作符   用法与 Java 完全一样。   Python 中没有“无符号”右移位操作符。

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/84479.html

(0)
上一篇 2024年 7月 27日
下一篇 2024年 7月 27日

相关推荐

关注微信