博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入总结嵌入式位操作运算符
阅读量:2434 次
发布时间:2019-05-10

本文共 3305 字,大约阅读时间需要 11 分钟。

位运算应用法则

清零取位要用与,某位置1要用或,取反和交换用异或

移位运算要诀

1.他们都是双目运算符,两个运算分量都是整形,结果也是整形。 

2.“<<”左移:右边空出的位上补0,左边的位将从字头挤掉,其值相当于乘2; 
3“>>”右移:右边的位被挤掉了,对于左边移出的空位,如果是正数则空位补0,若为负数,可能补0或1,这取决于不同的计算系统。 
4“>>>”运算符:右边的位被挤掉,对于左边移出的空位一概补上0;

位运算的应用(源操作数a 掩码b)

(1)按位与& 

1.清除某特定位(b中特定位置0,其余位为1,a=a&b) 
2.取某数中指定位(b中特定位置1,其余位为0,a=a&b) 
(2)按位或--| 
常用来将源操作数某些位置1,其它位置不变。(b中特定位置1,其余位为0,a=a|b) 
(3)位异或--^ 
相同为0,不同为1 
1 使特定位的值取反 
例如对数10100001的第2位和第3位翻转,则可以将该数与00000110进行按位异或运算。 
      10100001^00000110 = 10100111 
2 不引入第三变量,交换两个变量的值 
例如交换两个整数a=10100001,b=00000110的值,可通过下列语句实现: 
    a = a^b;   //a=10100111 
    b = b^a;   //b=10100001 
    a = a^b;   //a=00000110 
3.快速判断两个值是否相等 
举例1: 判断两个整数a,b是否相等,则可通过下列语句实现: 
return ((a ^ b) == 0) 
举例2: Linux中最初的ipv6_addr_equal()函数的实现如下: 
static inline int ipv6_addr_equal(const struct in6_addr *a1, const struct in6_addr *a2) 
return (a1->s6_addr32[0] == a2->s6_addr32[0] && 
a1->s6_addr32[1] == a2->s6_addr32[1] && 
a1->s6_addr32[2] == a2->s6_addr32[2] && 
a1->s6_addr32[3] == a2->s6_addr32[3]); 
}

可以利用按位异或实现快速比较, 最新的实现已经修改为:static inline int ipv6_addr_equal(const struct in6_addr *a1, const struct in6_addr *a2){return (((a1->s6_addr32[0] ^ a2->s6_addr32[0]) |    (a1->s6_addr32[1] ^ a2->s6_addr32[1]) |    (a1->s6_addr32[2] ^ a2->s6_addr32[2]) |    (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0);}

4.基于按位异或的加密解密算法 

class E 
{ public static void main(String args[ ]) 
char a1='十' , a2='点' , a3='进' , a4='攻' ; 
char secret='8' ; 
a1=(char) (a1^secret); 
a2=(char) (a2^secret); 
a3=(char) (a3^secret); 
a4=(char) (a4^secret); 
System.out.println("密文:"+a1+a2+a3+a4); 
a1=(char) (a1^secret); 
a2=(char) (a2^secret); 
a3=(char) (a3^secret); 
a4=(char) (a4^secret); 
System.out.println("原文:"+a1+a2+a3+a4); 
如果两个数相应的位上一样,结果就是0,不一样就是1 
所以111^101=010 
那加密的过程就是逐个字符跟那个secret字符异或运算. 
解密的过程就是密文再跟同一个字符异或运算 
010^101=111

二进制补码运算公式:

-x = ~x + 1 = ~(x-1) 

~x = -x- 
-(~x) = x+ 
~(-x) = x- 
x+y = x - ~y - 1 = (x|y)+(x&y) 
x-y = x + ~y + 1 = (x|~y)-(~x&y) 
x^y = (x|y)-(x&y) 
x|y = (x&~y)+y 
x&y = (~x|y)-~x 
x==y: ~(x-y|y-x) 
x!=y: x-y|y-x 
x< y: (x-y)^((x^y)&((x-y)^x)) 
x<=y: (x|~y)&((x^y)|~(y-x)) 
x< y: (~x&y)|((~x|y)&(x-y))//无符号x,y比较 
x<=y: (~x|y)&((x^y)|~(y-x))//无符号x,y比较

应用举例

(1) 判断int型变量a是奇数还是偶数 

a&1 = 0 偶数 
a&1 = 1 奇数 
(2) 取int型变量a的第k位 (k=0,1,2……sizeof(int)),即a>>k& 
(3) 将int型变量a的第k位清0,即a=a&~(1< (4) 将int型变量a的第k位置1, 即a=a|(1< (5) int型变量循环左移k次,即a=a<>16-k (设sizeof(int)=16) 
(6) int型变量a循环右移k次,即a=a>>k|a<<16-k (设sizeof(int)=16) 
(7)整数的平均值 
对于两个整数x,y,如果用 (x+y)/2 求平均值,会产生溢出,因为 x+y 可能会大于INT_MAX,但是我们知道它们的平均值是肯定不会溢出的,我们用如下算法:

int average(int x, int y)   //返回X,Y 的平均值{    return (x&y)+((x^y)>>1); }

(8)判断一个整数是不是2的幂,对于一个数 x >= 0,判断他是不是2的幂

boolean power2(int x) 

return ((x&(x-1))==0)&&(x!=0); 
}

(9)计算绝对值

int abs( int x ) 

int y ; 
y = x >> 31 ; 
return (x^y)-y ; //or: (x+y)^y 
(10)取模运算转化成位运算 (在不产生溢出的情况下):a % (2^n) 等价于 a & (2^n - 1) 
(11)乘法运算转化成位运算 (在不产生溢出的情况下):a * (2^n) 等价于 a<< n 
右边空出的位上补0,左边的位将从字头挤掉,其值相当于乘2; 
(12)除法运算转化成位运算 (在不产生溢出的情况下):a / (2^n) 等价于 a>> n 
右边的位被挤掉。对于左边移出的空位,补零,其值相当于除2; 
例: 12/8 == 12>>3 
(13) a % 2 等价于 a & 1 
(14) if (x == a) x= b; 
  else x= a; 
  等价于 x= a ^ b ^ x; 
(15) x 的 相反数表示为 (~x+1) 
(16) 实现最低n位为1,其余位为0的位串信息:~(~0 << n) 
(17)截取变量x自p位开始的右边n位的信息:(x >> (1+p-n)) & ~(~0 << n) 
(1)截取old变量第row位,并将该位信息装配到变量new的第15-k位:new |= ((old >> row) & 1) << (15 – k) 
(19)设s不等于全0,代码寻找最右边为1的位的序号j: 
for(j = 0; ((1 << j) & s) == 0; j++) ; 
return j;//由于1每次左移过程中只要遇到1此时相与为1,返回此时的位置J

转载地址:http://zvomb.baihongyu.com/

你可能感兴趣的文章
K8S精华问答 | Kubernetes集群不能正常工作,难道是防火墙问题?
查看>>
5G精华问答 | 什么是5G?5G与LTE有什么关系?
查看>>
虎牙直播在微服务改造方面的实践和总结
查看>>
微服务精华问答 | 在使用微服务架构时,您面临哪些挑战?
查看>>
Kubernetes 调度器实现初探
查看>>
边缘计算精华问答 | 边缘计算有哪些应用场景?
查看>>
如何用30分钟快速优化家中Wi-Fi?阿里工程师有绝招
查看>>
【C语言】C语言中常用函数源代码【strncpy ,strncat ,strncmp】
查看>>
【Java】【多线程】—— 多线程篇
查看>>
【Java】【数据库】知识重点——数据库篇
查看>>
【Java】学习总结 —— HashMap之put()方法实现原理
查看>>
【计算机网络】【TCP】如何讲清楚Tcp的三次握手和四次挥手?
查看>>
【Java】-- Java核心知识点总结
查看>>
【数据库】突破单一数据库的性能限制——数据库-分库分表总结 2018-9-20
查看>>
Slurm——作业调度处理
查看>>
Lustre 维护
查看>>
Lustre—磁盘配额测试
查看>>
SSH加密密码中的非对称式密码学
查看>>
Mac Redis安装入门教程
查看>>
python3安装教程配置配置阿里云
查看>>