0基础学算法 第七弹 位运算

  今天要讲的内容主要分为两个大块,一个呢就是位运算,另一个呢就是关于二进制的原码反码补码,位运算的应用也算是比较多的了,进行位运算有时候可以省略不少事情呢,当然,也不是说不会位运算就会天崩地裂,毕竟事实上,在学位运算之前,我都是用其他方法来强制性模拟位运算(当时我并不知道什么是位运算)不过多学一些也是好的,省事儿,而且更快

  一,二进制的原码反码和补码

  相信二进制没有人不熟悉的,逢二进一,一个二进制数由0和1组成,他的最高位就是他的正负符号,0是正数,1是负数,例如10001000,这就是一个负的二进制数,当然最高位是0就是正数

  原码之所以叫做原码,必然是因为它就像是万物之源,补码、反码都是在他的基础上变化的,当最高位是0的时候,也就是正数的时候,原码==反码==补码

  以下关于反码及补码的概念是基于最高位是1的情况(负数的情况)

  反码,顾名思义,是原码颠倒过来的样子,除了最高位表示负号的那个“1”不变以外,其他的数位上的数  全部取反,1变0,0变1,假设原码为1001010100,它的反码就是1110101011,再假设原码是0111001,它的反码就是0111001,是不是有点奇怪,哈,我前面说过了,当原码是正数的时候,原码==反码==补码

  补码,在原码是正数的情况下是等于原码或者反码的,但是在负数情况下,他恰好是反码加1,比如原码是100000,反码就是111111,补码就是1000000

  二,进入正题,位运算

  在系统的讲位运算之前,先给大家一张图表,方便大家查询

  

   注明:位运算符号在c++中用法同算数运算符

  首先是&

  其实位运算不复杂,理解了就好,比如说&,把他理解成1代表true,2代表false,1&&2,明显为false(2),2&&2明显也为false(2),只有1&&1的时候才为true(1);

  但是这是if语句里面的判断方法,而‘&’的运算方法是这样的,比如1010&0011,运算过程如下图

  过程如右图

  至于|的话。。。就是上下两个数只要有一个为1,结果就为1啦,如1100|0011=1111

  ‘~’!也比较好理解,做它的运算的时候,只需要传一个二进制数,针对每一位进行运算可以从在每一位上如~1001=0110;

  ^,亦或,算起来也比较简单,只要两位不相等,结果就为1,举例,1001^0101=1100

我觉得有图就不用我多讲了吧/狗头/滑稽

   最后一组"<<"和”>>"这个是左移和右移的操作

  请看

  int类型的二进制是32位的,而long long是64位,左移和右移

  例如,给出一个标准的32的int类型00000000000000000000000000000001,当我们使用左移的时候,整体忘左移,并在后面补零

右移也相似,只不过是低位被挤掉了,高位补0

 

 

  有一道题,可以通过位运算做的很简便,但如果你不会位运算的话。。。就另当别论了

  如果你不用位运算,你要写很复杂的代码,但是用了,你就只要10行代码,如假包换(虽然我绝对不换)

  题目链接→https://www.luogu.com.cn/problem/P1100

   看到题目,很清晰了,首先录入两个字符串,然后将它转成二进制,接着把前16位和后16位的数交换位置,最后结果转成十进制输出!好,完美。。。

  停!

 今天利用我们学的位运算压根不用这么麻烦!

  直接用上我们的左移"<<"和右移">>"啊!

  只要左移后16位,右移前16位不就好了?

  废话不多说,大家请看最短代码!

#include<bits/stdc++.h>
using namespace std;
unsigned int x;
int main(){
    cin>>x;//录入x
    cout<<((x<<16)|(x>>16));//将左移16位后的x和右移16位的x用或"|"将他们重新连起来
    return 0;//完美
}

  完美撒花🎉🎉🎉🎉🎉🎉🎉

  如果觉得我讲的不错的,麻烦点个关注➕,点个赞👍,以后还会持续更新的😀

ps:欢迎大家进群 群号:1031457671

posted @ 2020-06-12 20:05  球君  阅读(567)  评论(0编辑  收藏  举报
View Code