常用位操作
操作 | 含义 | |
---|---|---|
& | 按位与 | 两个位都为1时,结果才为1 |
| | 按位或 | 两个位都为0时,结果才为0 |
^ | 按位异或 | 两个位相同为0,相异为1 |
~ | 按位取反 、 | 0变1,1变0,包括最高位 |
<< | 左移 | 左移若干位,高位丢弃,低位补0 |
>> | 右移 | 右移若干位,正数补0,负数补1 |
注意:1.位操作只能用于整形数据,对float和double类型进行位操作会被编译器报错。 2. 位操作符的运算优先级比较低,因为尽量使用括号来确保运算顺序。
相关知识点
-
异或相关
- 任何数与0异或结果为其自身: a^0=a
- 任何数与自己异或,结果为0: a^a=0
- 异或满足交换律和结合律: aba=(aa)b=b
-
移位相关
-
左移<<
左移若干位,高位丢弃,低位补0,其值相当于乘以2,例如:3<<1=3, 3<<2=6。
对于有符号数,不一定适用,因为有符号数的最高为是符号位,例如对于01000000…0000,左移1位,就变为10000000…0000,变为了int类型所能表示的最小值是-2147483648.
对于无符号数,则完全适用。
还有一种情况是,移位超过超过该数值类型的最大位数时(例如int 32位),编译器会按照余数值来移位
int i = 1, i = i << 33; // 33 % 32 = 1 左移1位,i变成2
-
右移>>
右移若干位,正数补0,负数补1,相当于除以2。
对于有符号数,右移符号位不变,当移动的位数超过类型的长度时,会取余数,然后移动余数个位.
对于无符号数,则完全适用。
-
-
原码、补码、反码相关
正数5:
5的二进制是:00000101 原码:00000101 反码:00000101 补码:00000101
负数:-5:
5的二进制是:00000101
原码:10000101//就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
反码:11111010//负数的反码是对其原码逐位取反,但符号位除外。
补码:11111011//负数的补码是在其反码的末位加1。
注:一个字节由8个二进制位组成,这里一个int型表示两个字节
相关技巧
-
判断奇偶
x&11,则x为奇数;x&10,则x为偶数
-
交换两数
x=x^y, y=x^y, x=x^y
-
求绝对值
int abs(int a) { int b=a>>31; //取最高位,正数为0,负数为-1 return a^b-b; //b=0,a^b-b=a^0-0=a || b=-1,a^b-b=a^-1+1=~a+1=-a }
-
判断两个数的符号是否相同(a^b)
- 如果a和b都为正数,则最高位都为0,则最高位异或为0,则a^b>=0;
- 如果a和b都为负数,则最高位都为-1,则最高位异或为0,则a^b>=0;
- 如果a和b一正一负,则最高位异或为-1,则a^b<=0;
-
i+(~i)=-1
例如:i:1000 0101;~i:1111 1010
相等于将所有二进制位置为1,十进制结果为-1,负数的绝对值等于负数按位取反+1,因此为-1.
-
x & (x - 1) ,可以将最右边的 1 设置为 0。
这个技巧可以用来检测 2的幂,或者检测一个整数二进制中 1 的个数,又或者别人问你一个数变成另一个数其中改变了多少个bit位,统统都是它
持续完善。。。
参考
1.https://mp.weixin.qq.com/s/63pmj6Vxbec1u-iEZnbAxw
2.https://blog.csdn.net/hk_john/article/details/70231705
3.https://blog.csdn.net/qq_34364995/article/details/80544465
4.https://blog.csdn.net/weixin_38590073/article/details/72862066
原文链接: https://www.cnblogs.com/depth-perception/p/12603217.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;
也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/378028
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!