目录

一、先补充一下移位的概念

1.操作对象

2.移位运算符

二、位移的应用案例(15种)

1.判断奇偶性

2.取int型变量a的第k位 (k=0,1,2……sizeof(int))

3.将int型变量a的第k位清0

4.将int型变量a的第k位置1

5.int型变量循环左移k次

6.int型变量a循环右移k次

7.整数的平均值

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

9.用位运算符交换两个整数

10.计算绝对值

11.取模运算转化成位运算 (在不产生溢出的情况下)

12.乘法运算转化成位运算 (在不产生溢出的情况下)

13.除法运算转化成位运算 (在不产生溢出的情况下)

14.判断赋值

15.x的相反数

三:移位运算的取舍

参考:C语言按位运算妙用


一、先补充一下移位的概念

1.操作对象

移位的操作对象是二进制数据(整数数据以补码的形式存储在计算机内存中)

//例如int类型5在计算机中存储为 0000 0000 0000 0000 0000 0000 0000 0101

2.移位运算符

<< 左移:左边丢弃,右边补0

>> 右移:算术右移,右边丢弃,左边补原来的符号位;逻辑右移,右边丢弃,左边补0

&:按位与,按位与&,1与1为1,1与0,0与0均为0

|:按位或,按位或|,1或1为1,1或0为1,0或0为0

^:异或,相同为0,相异为1

~:按位取反,0转1,1转0

二、位移的应用案例(15种)

1.判断奇偶性

        其实就是利用了整形变量最后一位来判断奇偶性,奇数存储在计算机中的补码最低位一定是1,而偶数存储在计算机中的补码最低位一定是0,与1按位与运算即可得到0或1。

a&1   = 0 偶数             //2的补码 0000 0000 0000 0000 0000 0000  0000 0010

a&1   = 1 奇数             //3的补码 0000 0000 0000 0000 0000 0000  0000 0011

2.取int型变量a的第k位 (k=0,1,2……sizeof(int))

a>>k&1

3.将int型变量a的第k位清0

a=a&~(1<<k)

4.将int型变量a的第k位置1

a=a|(1<<k)

5.int型变量循环左移k次

(设sizeof(int)=16)
a=a<>16-k   

6.int型变量a循环右移k次

(设sizeof(int)=16)
a=a>>k|a<<16-k

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

boolean power2(int x)
{
    return ((x&(x-1))==0)&&(x!=0);
}

9.用位运算符交换两个整数

这个是一种比较特殊的交换数据的方式,不需用第三个容器来交换数据

void swap(int x , int y)
{
    x ^= y;
    y ^= x;
    x ^= y;
}

例如:x=10,y=6;

x:             0000 0000 0000 0000 0000 0000 0000 1010

y:             0000 0000 0000 0000 0000 0000 0000  0110

x=x^y: x= 0000 0000 0000 0000 0000 0000 0000  1100

y=y^x: y= 0000 0000 0000 0000 0000 0000 0000  1010

x=x^y: x= 0000 0000 0000 0000 0000 0000 0000  0110

10.计算绝对值

int abs( int x )
{
  int y ;
  y = x >> 31 ;
  return (x^y)-y ;        //or: (x+y)^y
}

11.取模运算转化成位运算 (在不产生溢出的情况下)

a % (2^n) 等价于 a & (2^n - 1)

12.乘法运算转化成位运算 (在不产生溢出的情况下)

利用了数据在计算机中存储的形式特点,数据左移n位就是变为原来的2^n倍

a * (2^n) 等价于 a<< n

例如:int a=10; a*=2^3;

计算机中补码形式为(0000 0000 0000 0000 0000 0000 0000  1010) 

a*=2^3;(0000 0000 0000 0000 0000 0000 0101 0000)

即,补码有效数据左移3位,数据变为原来2^3倍。

溢出情况请参考我的另一篇博客:https://mp.csdn.net/mp_blog/creation/editor/129356986

13.除法运算转化成位运算 (在不产生溢出的情况下)

a / (2^n) 等价于 a>> n

14.判断赋值

if (x == a)        //等价于 x= a ^ b ^ x;
    x= b;
else
    x= a;             

15.x的相反数

利用了正负数在计算机中补码的性质。

 (~x+1)

三:移位运算的取舍

        位移运算从执行上看效率要更高一些,但是考虑到具体的项目开发和其他环境问题,要结合具体情况进行比较。

本文章仅仅是总结整理了常用的位运算的公式技巧以及原理!

参考:C语言按位运算妙用

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐