凶悍的位运算


补上篇文章的坑,今天就来介绍下位运算。

一,位运算的意义

虽然网上搜到不少大佬的介绍,但问题是,萌新不太懂啊,只能自己从自己学到的出发,以后遇到了继续添加。

1.较高的执行效率
2.较低的空间需求
3.特殊需求

有使用价值,我们才更多会去使用,去多学它。

二,什么是位运算?

位运算就是直接对整数在内存中的二进制位进行操作。

例如: 1 & 2 = 0b 0001 & 0b 0010 = 0b 0000 = 0

三,位运算简介

1.位运算符号

在这里插入图片描述
& :与运算 有0为零,同1出1。

| :或运算 全0为0,有1是1

^ :异或运算 相同为0,不同为1

~ :取反运算 和原情况相反

下面是一些基本情况的运算表。
在这里插入图片描述右移 : >>
例如: 12 >> 2 =
0b 0000 1100 右移两位 结果为 0b 0000 0011 十进制为3
在不超过范围内,12 >>2 相当于12除以4(2的2次方)

左移 : <<
例如: 12 << 2 =
0b 0000 1100 左移两位 结果为 0b 0011 0000 十进制为48
在不超过范围内,12<< 2 相当于12乘4(2的2次方)

注意:右移时,左侧补的是符号位。
例如 -32 >> 2
1000 0000 0000 0000 0000 0000 0010 0000原
1111 1111 1111 1111 1111 1111 1110 0000补

右移 2位

1111 1111 1111 1111 1111 1111 1111 1000补
1000 0000 0000 0000 0000 0000 0000 1000原
此时符合补码转原码机制“符号位不变,数值位按位取反,末位在加一”。
-32 >> 2 的结果为-8

但是在某些场合(比如,单片机的程序),需要右移时,左侧补0,且恒补0!
可以在这种场合中,可以将相关变量或值,定义(或强转)为无符号数!
unsigned char

2.位运算符号优先级!

在这里插入图片描述

四,位运算的使用

1.较高的执行效率

上一篇有关哥德巴赫猜想中运用了位运算,其中有不少地方为了更好的速度。
例如
1.1取余运算
判断一个数(num)是不是偶数
一般操作,num % 2 ,其实这等同于 num & 1
0001 0011B num
&
0000 0001B 1
0000 0001B num % 2 == 1 遵循有0出零,全1为1原则.
同样,num % 8 == num & 7
**一般小技巧总结:**num % (2^n) += num & (2^n)-1;
当然,却也只能针对 2的幂数。
1.2除以运算
例如,num / 4 == num >> 2。原因上面也说了。我不是来水字的。
**一般小技巧总结:**乘以2的倍数(除以2的倍数)都可以用左(右)移实现。
但是要注意范围!!!
有人会问这有啥作用?
你看。
num * 94 == (64 +32-2)*num == (num << 6) +(num << 5)-(num << 1)
至于,位运算比乘除运算快多少?
这篇文章说了原因和情况
链接: https://blog.csdn.net/Hk_john/article/details/69942784
1.3减法运算
7 - num =?
0000 0011B 3
^
0000 0111B 7
0000 0100B 结果为4 =7-3 (相同为0,不同为1)
额,这也是位运算的运算。不过没快那么多。不总结了。嘿嘿。

2.较低的空间需求

还是在歌德巴赫猜想里的运算使用这一想法

在这里插入图片描述用每一个位来代替·一个数字,如果它是质数,就为零,不是质数为1。
相当于把指定位数的数置1,或者置0.
还记得这个宏吗?
在这里插入图片描述1.置位:把某一字节指定位置为1

0123 4567字节下标xxxx  xxxx某字节

把某一字节指定位置为1: num |= 1 <<( (index)^7)

2.清位:把某一字节指定位置为0
在这里插入图片描述
一样的用下标,不过这次用与运算。而且发现没?这个数和上面的有关系。
在这里插入图片描述
按位取反。~0111 1111b == 1000 0000b 所以
**把某一字节指定位置为0: num &= ~(1 << (index)^7)

3.取位:取得某一位的值
在这里插入图片描述为甚么要 != 0呢?
哈哈,在这里插入图片描述
num & (1<<(index) ^ 7)只能使那一位是1,或0。但取位的结果为1或0,所以用!=0

通过以上三个基本方法,就可以使字节操作变到位操作了。

3.特殊需求。

目前笔者没用到。所以以后添加。

4.实例

12.11添加

4.1加密与解密

你加密明文,自己设置密钥,设置运算规则。
明文:1011 0101
密钥:0011 1101
密文:1000 1000(使用的是异或运算)
你朋友解密,有你给的规则及密钥
密钥:0011 1101(同密文异或运算)
明文:1011 0101
如此·,只有知道密钥和运算规则的可以加密解密。而且如果密钥位数达到16,32时,其解开难度成幂数增长。所以挺有用的。

五,位运算小结

本来还想加一点实例,这一次就不了。
以上就是有关位运算的一点基本知识,和小应用了。

好吧,我没啥总结的了。
就是内存很可怜,要保护它,可以加快速度,减少内存使用的就优化。
不能只凭个人舒服就简单了事。有些题目,不优化,也可以解出来,
往往生活中的问题,并不是ABCD,四个选项,甚至正确答案会在EFG中,有时候甚至我们需要用XYZ的思维去思考。

笔者水平有限,目前只能描述以上问题,如果有其他情况,可以留言,有错误,请指教,有继续优化的,请分享,谢谢!

2019年12月09日 通院2楼

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值