位运算总结--C语言

1.类型转换

  1. int main()
  2. {
  3.     char a = 129;
  4.     char b = 255;
  5.     char c = -1;
  6.     int  d = a;
  7.     printf("%d\n",d);//-127
  8.     d = b;
  9.     printf("%d\n",d);//-1
  10.     d = c;
  11.     printf("%d\n",d);//-1
  12.     unsigned char e = 300;
  13.     unsigned char f = -1;
  14.     unsigned char g = 255;
  15.     d = e;
  16.     printf("%d\n",d);//44
  17.     d = f;
  18.     printf("%d\n",d);//255
  19.     d = g;
  20.     printf("%d\n",d);//255
  21.     return 0;
  22. }

2.统计一个字节数据中二进制1的个数:

  1. //统计一个字节数据中二进制1的个数,法三法四不如法一法二好
  2. //8->1,5->2,127->7,-1->8
  3. //法三
  4. int Bits(unsigned char n)//unsigned  防止出现负数情况,
  5. {
  6.     int count = 0;
  7.     while(n != 0)
  8.     {
  9.         if(n%2 == 1)//和十进制类似,得个位
  10.         {
  11.             count++;
  12.         }
  13.         n /= 2;// 丢个位,如果是-1,结果为0,直接退出,此时打印-1含有的1为1个,而真实-1的值(1111 1111)有八个,明显错误。
  14.     }
  15.     return count;
  16. }
  17. //法四
  18. int Bits(unsigned char n)
  19. {
  20.     int count = 0;
  21.     while(n != 0)
  22.     {
  23.         if((n&1) != 0)
  24.         {
  25.             count++;
  26.         }
  27.         n >>= 1;
  28.     }
  29.     return count;
  30. }

法一//x & (x - 1),即求二进制1的个数,实用

  1. int Bits(unsigned c,char n)
  2. {
  3.     int count = 0;
  4.     while(n != 0)
  5.     {
  6.         n &= (n-1);
  7.         count++;
  8.     }
  9.     return count;
  10. }

法二//利用空间换时间,手动写好数的值,保存数组里面,直接查找,简称查表法

  1. int Bits(unsigned char n)
  2. {
  3.     char bit[256] = {0,1,2,2,1,2,2,3,1,2,2,3};//即保存的是0,1,2,3,4,5,6,7,8,9,10,11里面的二进制中1的个数,保存了才能查到,否则为零
  4.     return bit[n];//返回位数
  5. }
  6. int main()
  7. {
  8.     printf("%d\n",Bits(5));//2法一的值//2法二的值
  9.     printf("%d\n",Bits(9));//2//2
  10.     printf("%d\n",Bits(7));//3//3
  11.     printf("%d\n",Bits(3));//2//2
  12.     printf("%d\n",Bits(64));//1//0
  13.     printf("%d\n",Bits(-1));//8//0
  14. }

 

3.易错点

  1. int main()
  2. {
  3.     printf("%d\n",-1 >> 1);//-1,右移一位,末尾去1,然后在头加符号位1,所以还是 1111  1111,即-1
  4.     printf("%d\n",255 >>1);//127
  5.     char b = 200;
  6.     //b的二进制为1100 1000 符号位为1,即负数,真正的值要取反加1, 变为-0011 1000,即-56(char 类型的范围是-128~127)
  7.     printf("%d\n",b);//-56
  8.   
  9. float c = 3.4;
  10.     printf("%f\n",c);//3.4
  11.     printf("%d\n",c);//特别大的数
  12.     
  13.     float a = 5/2;//2.000000
  14.     float d = 5.0/2;//2.500000
  15.     float e = (float)5/2;//2.500000,强转的优先级高,先算强转
  16.     float m = (float)(5/2);//2.0
  17.     printf("%f,%f,%f,%f\n",a,d,e,m);
  18.     //求不同类型字节数
  19.     printf("%d\n",sizeof(char));//1
  20.     printf("%d\n",sizeof(short));//2
  21.     printf("%d\n",sizeof(int));//4
  22.     printf("%d\n",sizeof(long));//4
  23.     printf("%d\n",sizeof(long long));//8
  24.     printf("%d\n",sizeof(float));//4
  25.     printf("%d\n",sizeof(double));//8
  26.     printf("%d\n",sizeof(1));// 整数默认为整形
  27.     printf("%d\n",10%3);
  28.     //求余
  29.     printf("%d\n",-5%3);//-2
  30.     printf("%d\n",5%(-3));//2
  31.     printf("%d\n",(-5)%(-3));//-2
  32.     //  <, >容易出错,不能连等
  33.     if(10 > 5 > 8)//假,不能连续比较,10 > 5的值为1,小于8
  34.     {
  35.         printf("真\n");
  36.     }
  37.     else
  38.     {
  39.         printf("假\n");
  40.     }
  41.     //!= ,赋值的利用率远远大于等号的利用率,所以把=看成赋值,把==看成等于
  42.     if(a == b)
  43.     {
  44.         printf("==\n");
  45.     }
  46.     else
  47.     {
  48.         printf("!= \n");
  49.     }
  50.     return 0;
  51. }

1.表达式1 && 表达式2 //表达式1为假,2不做运算

表达式1 || 表达式2 /表达式1为真,表达式2不做运算

2.按位异或

10           0000 1010

11           0000  1011

10 ^ 11    0000  0001  

3.按位左移,按位右移

11 << 1    0001 0110         变为:22 = 11*2 (按位左移,右边补零)

11 << 2    0010 1100         变为: 44 = 11*2*2

 11 >> 1   0000 0101          变为:5 = 11/2 (按位右移,左边补符号位)

-1 >> 1    1111 1111             -1为1111 1111 (右移补符号位,右移一个,右边去掉一个1,符号位为1,所以左边再加1)

4.表达式1 ? 表达式2 : 表达式3 //表达式为真,执行表达式2,表达式为假,执行表达式3

a > b ? a : b;(a > b,执行a,否则,执行b);

5.位总结:定符号,定数字,构造数字


&与     |或    ^异或

定符号:取零&1,取1 | 0,^(1和1还是0,0和0还是0,0和1变为1)

1.去掉x最后一位 

eg:(101101->10110)   右移    x >> 1

2.在x最后加0 

eg:(101101->1011010)    左移   x << 1

3.在x最后加1 

eg:(101101->1011011)    左移再或1   (x << 1) | 1

4.把x最后一位变1   

eg:(101100->101101)    或1    |1

5.把x最后一位变0

eg:(101101->101100)    右移再左移  或者 1取反再与x       ((x >> 1) <<1)      (~1)& x

6.把x最后一位取反 

eg:(101101->101100)     x^1

7.把x第倒数k位变1 

eg:(101001->101101 ,k = 3)       1左移k-1位再或x   x | (1 <<(k-1))

8.把右数第k位变0 

eg:(101101->101001,k = 3)       1左移k-1位再取反再与x    x &(~(1<<(k-1)))

9.把x右数第k位取反 

eg:(101001->101101,k = 3)     左移k-1位再异或x         x ^ (1 << (k-1))

10.取x末尾三位 

eg:(1101101->)101           x & 7

11.取末尾K位  1左移k位减1再与1   

eg:(1101101 ->1101,k=4)           x & ((1 << k)-1)

12.取右手第k位     

eg:(1101101->1,k = 4)    (x >> k) & 1

13.右手连续的1 变连续的0   

eg:(100101111->100100000)   x & (x + 1)

14.右起第一个0变1

eg:(100101111->100111111)      x | (x + 1)

15.右边连续的0变1    

eg:(11011000->110111111)     x | (x-1)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值