1 与(&)
1. 与(&)运算实现求余%运算
在计算机里整数求余运算比较低效,在对2的整数幂进行求余时,可以使用&来优化
如: a对2 ^ n (n为自然数)求余:
a % (2 ^ n) = a & ((2 ^ n) - 1) // 如 a % 4 = a & 0x3
判断奇数偶数时,可以与1相与
if (n & 0x1 == 0x1) {
// printf("n 是奇数");
}
2. 计算一个整数2进制中有多少个1
利用n = n & (n – 1) 用来将最低位的1变为0
count = 0
while (n)
{
n &= (n - 1);
count++;
}
3. 判断一个数是否是2的整数次幂
如:判断n是否是2的整数次幂,2的整数次幂即整数的二进制表示中只有一个1,如(2–> 010b 4–>0100b等)
if (! (n & (n - 1))) {
// printf("n is 2 的整数次幂");
}
4. 获取一个整数2进制最低位的1(最右边的1)
n & -n // 最低位的1被与运算保留下来, 同样可以使用 n & -n == n 来判断n是不是2的整数次幂
n & (~n + 1) // ~n+1即对n取反再加1,这个即得到-n的补码 ~n+1=-n
有时候,我们希望得到整数二进制最低位1的位置:
/* Find the First bit in uint8_t data */
uint8_t FindFirstBit_u8(uint8_t n)
{
n = (n-1) & ~n;
n = ((n & 0xAA) >> 1) + (n & 0x55);
n = ((n & 0xCC) >> 2) + (n & 0x33);
n = ((n & 0xF0) >> 4) + (n & 0x0F);
return n;
}
/* Find the First bit in uint16_t data */
uint16_t FindFirstBit_u16(uint16_t n)
{
n = (n-1) & ~n;
n = ((n & 0xAAAA) >> 1) + (n & 0x5555);
n = ((n & 0xCCCC) >> 2) + (n & 0x3333);
n = ((n & 0xF0F0) >> 4) + (n & 0x0F0F);
n = ((n & 0xFF00) >> 8) + (n & 0x00FF);
return n;
}
/* Find the First bit in uint32_t data */
uint32_t FindFirstBit_u32(uint32_t n)
{
n = (n-1) & ~n;
n = ((n & 0xAAAAAAAA) >> 1) + (n & 0x55555555);
n = ((n & 0xCCCCCCCC) >> 2) + (n & 0x33333333);
n = ((n & 0xF0F0F0F0) >> 4) + (n & 0x0F0F0F0F);
n = ((n & 0xFF00FF00) >> 8) + (n & 0x00FF00FF);
n = ((n & 0xFFFF0000) >> 16) + (n & 0x0000FFFF);
return n;
}
2 或(|)
(待补充)
3 异或(^)
1. 异或的重要性质
-
一个数与自身异或,总是为0
x ^ x = 0
可以用来判断两个变量是否相等,如c语言中判断,变量a与b是否相等
if ((a ^ b) == 0) { // printf("a 与 b相等") }
-
一个数与0异或,总是为自身
x ^ 0 = x
2. 不使用临时变量交换两个整数的值
交换两个整数的值,通常做法是借助临时变量,然后交换,如:
tmp = a
a = b
b = tmp
利用异或的性质,不用临时变量也能交换两个数的值,过程如下:
a ^= b
b ^= a
a ^= b
4 移位
-
左移n位等于原数值乘以2的n次方,要注意避免溢出(正数变负数)
-
逻辑右移n位等于原数值除以2的n次方,注意负数右移的情况:
x >> n = floor(x / (2 ^ n)) // 例如: -5 >> 1 = -3 而非-2
参考:
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/201891.html