好同学们
我们说一下这个二进制和位运算
以及一系列需要注意的点啊
这节课不建议跳过啊
就是他会他一定会戳中某些朋友
这个呃就是学习上的一些没有注意到的东西
尤其是这个第十个为什么这么设计二进制是吧
你可能上学的时候老师就跟你说
记住就行了对吧
那其实它是有非常精妙的理由的啊
好我们一点点来
首先我们先介绍一下二进制和V的概念
就是你我们我们日常使用十进制嘛对吧
我们比如说写一个103
就认为三是还有几个十的零次方三个
那还有几个十的一次方的零个
还有几个十的平方的一个对吧
所以你加出来是100+3是吧
你有三个十的零次方和一个十的平方
那就是得到103
这就是十进制嘛对吧
那么二进制呢其实一样的啊
二进制也一样的
对于二进制来说
他这个比如我写一个状态
0101这几是吧
那你就代表这是二的零次方
这是二的一次方
是二的平方
这是二的三次方对吧
那它是几呢
呃呃你有一个二的零次方诶
所以你有一个一
你有一个二的平方
所以你有一个四
那加起来是吧
这个这个状态就代表五对吧
这就是二进制
很简单
你任何数字都可以变成二进制和十进制
我看你怎么转化而已对吧
在计算机里面呢
它只认二进制
所有但凡遇到十进制的地方
那都是转换出来给人看的
或者转换出来再给人用的理解
这意思吧
就是对于计算机来说
它的底层只有二进制
他机器上只能做二进制的计算
而且在机器层次上
他只能做位运算相关的是吧
也就是说一切算术运算都是未运算拼出来的啊
这个我们我们接下来再说是吧
好这就是所谓的二进制了
那你我我们举例子的话就是四位的对吧
但是你要知道在呃一般语言中
包括java c c加加里是吧
这整形有32位啊
这个long类型呢
这个有64位对吧啊
那你就相应的你去扩充就行了嘛
我们这四位的话
你能表示从哪到哪的范围的一个数字呢
如果是无符号整数的话对吧
我们看一下什么叫无符号整数呢
就是你把所有的位都用来做数值位
而且没有负数的概念
那这样的话就是无符号整数
那你看你这个如果是四位的话
你就是从0000
它就代表的背后的值是多少
十进制的零对吧
一直到1111
这是多少呢
哎有一个一一个二
一个四
一个8~15对吧
这是15
所以呢就是你你二进制如果用四位来表达
它就能表达一下0~15对吧
四位的情况下它能表示几个数二的四次方个数
零到15一共16个数嘛是吧
二的四次方正好16个
那么它的范围呢它的范围是多大呢
它的范围就是从0~2的四次方
减一的范围对吧
从0~15嘛
那你整形32位
如果是无符号的话呢
那就是能表达0~2的32次方减一个
这这这个范围的数一共二的32次方个对吧
64位呢就是0~2的64次方减一
这是无符号数的含义对吧
无符号数怎么表达
就已经跟大家解释清楚了
所有的数值都用来拼值
所有的V都用来拼直
而且没有符号的概念啊
这就是无符号的二进制表达
那么有符号呢
有符号可能就比较稍微复杂一点了是吧
二进制假设我们还是拿四位来举例啊
因为太多位你举例你得写半天
是不是二进制
假设你有四位
假设你有四位
那么如果你是有符号
就是你既可以表示正
也可以表示负
也可以表示零对吧
它总体肯定还是二的四次方
一共16个数
但是在这个16个数中
它分配给负数的范围和非负数的范围
其实是非负数的范围其实是不太一样的对吧
或者说负数里面有八个
正数和零里面也也分配了八个好
我们先看非负数
非富
那零怎么表达
0000怎么理解
我们把最高位呢叫做符号位啊
他不用来做数值了
它用来做符号
那么最高位的零就认为它是一个非负的
那它是那它非负里面它是多少值呢
后面是数值位啊
零这个值那一你怎么表达呢
首先你是一个非负的
所以最高位符号位用零表示后面是001对吧
那你二怎么表达呢
你用零表示后面是010是吧
一直你七怎么表达呢
零后面是111唉
到这就结束了
如果你只有四位的话
从0~71共几个数
八个数
从0~71共八个数
算法零在内一共八个嘛对吧
它就只能表示这个范围了啊
那么我们说负数呢
你你你看你这个这些数字都是零对吧
表示它是符号
它是一个非负的
那么负数那就肯定最开头的
最左边这个最高的符号位
它一定是一
后面怎么去拼出来一个负数
好有点绕的啊
复数的表达有点绕的
听我讲啊
首先我们看如果你只有四位的话
你的一怎么表达
如果你四位的话
你的一怎么表达啊
一是哪个状态
怎么得到
我跟大家说啊
你先看它正数是哪个状态
0001对吧
然后你再去让它减一是哪个状态
0000对吧好
然后你再把这个状态每一位都取反
就是零变一一变成零都取反好
那么得到1111这个状态
它就是计算机里一的状态啊
你不用管什么什么源码补码
我告诉你没有用
计算机里不鸟这些
计算机里表达一永远是这个啊
永远是这个
那么我们再来举个例子啊
那你说太绕了是吧
那我就再给你举个例子
二还是一样的逻辑
你先看它正数是什么样
0010是二嘛对吧
它正数形式是二嘛对吧好
然后你让他干嘛减个一
它变成几
我们知道小学像小学做减法一样
你这个一你要你要减个一
那就借位借位
它减完了之后就是0001嘛对吧
001加个最末尾的一进位上去就变成了这个
所以他减一呢就是0001好
然后你再把它取反1110
这个啊它就是二的状态啊
他就是二的状态好我们再想
那么再举个例子啊
我们说七是什么状态
七是什么状态
你先看七是啥状态对吧
叫正数的形式
七是啥状态
七是这个
这是七
这是七对吧
然后呢你再把它减个一
它是啥状态
0110还是这个状态
那就是六
然后你再把它整体取反001
这就是夫妻计算机里就是这么表达的啊
好最后八是啥状态
它能表示在八
你先看它正数是什么样子
八嘛1000对吧
你再给他减个一
它变成啥011腰好
你再给它取反是啥
1000没错
八的二进制1000
啊就是这么表达的
所以我们来很简单是吧
我们再说一下逻辑
如果你是个负数的话
那么它取证完了之后再减一的那个状态取反啊
他正完了之后
他减一之后的状态再取反
就得到他的二进制表达了
好那么从二进制怎么知道它是负几呢
对吧你你正反你都得会啊
好我们来看啊
比如说我们拿这个状态来说
1001怎么确定它是负几
首先它最高位符号位是个一
一定是个负
对不对
那他是负极怎么看呢
整个状态取反整个状连同符号位在内
整个状态取反啥
0110
然后这个值加个一是谁
0111
这是几
这是七哦
所以你是七
理解怎么判断了吗
就是你拿到一个二进制状态的时候
你先看最高位
最高位是一
就因为他一定是个负
那它到底是负几呢
这个积怎么确定
就是整个状态取一个反取反
完了状态再加个一所搞出来的数值是多少
它就是负极好
同样道理
我们来看这个比较特殊的负81000
它是多少
首先它最高位是一
他一定是个负的
那它是负几呢
同样道理
你把它整个位取反0111
再给这个状态加个11000
这是几
你把它看作数值
八所以100状态它就是八
理解吗
这样一来我们如果你一个二进制有四位的话
它就可以表示从-8~-1到0~7这些数字
理解吗
他就可你这是多少个数
也是16个
一共也是16个
但是这16个中0~7这八个用来表示非负的
-8~-1这八个用来表示负的
所以非负和负数这个数是一样的
只不过非负这边多了一个零
要占一个对吧
那么八的状态就是1000
七的状态是1001
一直一的状态
1111
这可以说最高最最开头这一位是一的
所有状态都用完了
最开头这一位是一的所有状态都用完了
你看从0000000011直到1111
最开头是一的这些状态都用完了八个
然后从零开始00001直到最后的0111
开头为零的这个这些状态也用完了
0001直到111
所以正好严丝合缝对吧
那么大家就问了哦
我们来总结一下吧
我们来总结一下啊
什么呢
就是首先我们了解了二进制
然后无符号的那个好搞对吧
有符号的有点儿号对吧
那么我们来看对于这个二进制
无符号的都不说了
你拿所有的V都去拼值对吧
对于有符号的来说
非负的也简单
非负的就是开头一定是零
后面拿后面的东西去拼值嘛对吧
那么作为负数就分为两个逻辑
先是你定下一个负极
怎么得到它的二进制怎么做呀
把它搞成正数的状态
得到它
然后把这个状态减个一
得到下一个状态
再把这个状态取反给出来是啥状态
他就是六
就是你可以负任何对吧
负任何你都转成正数
这个状态减个一
然后整个状态呢再取反就得到了二进制里面
对应这个负数的二进制是啥对吧
还有就是当我知道了一个二进制的形式
当我知道了一个二进制的形式
我怎么确定它是负几呢
首先它开头是一
就已经确定它是负的了对吧
那它是负几呢
就是他的一决定它是一个负的对吧
它是负极
怎么看
就是整个状态整体取反
包括符号位在内都取反得到一个状态
然后再拿这个状态加个一所得到的状态
你就把它当做一个无符号数来确定它是负极哎
两套逻辑是吧
大家可以随意验证啊
当然你不验证也无所谓
我们后面的代码也会非常清晰的展示
这个东西啊
非常清晰地展示这个东西好
现在在你的脑海中就已经有个大困惑了
是有病吗
把复数的状态搞得这么绕
但是告诉大家
我讲的就是教材上的啊
复数的状态他为啥要搞得这么绕呢
它是有着非常精妙的理由的啊
我们将这节课会讲啊
还没到啊
来所以我们来这个看一下啊
我们讲了正数怎么用二进制表达
负数怎么用二进制表达
然后我们讲的所有的东西都是建立在这个
二进制是四位的情况下啊
二进制是四位的情况下是吧
但是它推广到32位或者64位呢
都是同理的啊
推广完了之后
那你说32位的数中属于负数的有几个呢
二的30一次方各啊
那属于非负的
属于非负的有几个呢
也是二的30一次方个
他俩一共是二的32次方个
只不过对于负数来说
它是从一一直到二的30一次方的对吧
对于非负来说
它是0~2的30一次方减一的对吧
就这么一个分布
那你自己就可以去拓展它到64位的long类型
也是这么干的
只要它是一个有符号数
就都是这么搞的理解哇
哦好的
那么在java中是没有无符号这个概念的
是吧啊
在C跟C加加中可能会有其他语言呢
也可能会有各自的规定
但是主大的原理是不会变化的啊
大的原理是不会变化的好
那么这就是这就是我们说的一个小的拓展
你把它自己的扩充到32位到64位对吧
好的
那么我们就来实际的打印一下这个二进制
以及教大家怎么直接定义二进制的变量
和16进制直接拼出来这个变量是啥好
我们来看看展示一下
首先啊这个打印的二进制的函数
我们下面会讲的
你先把它当做一个黑盒对吧
这个这个函数的功能
就是打印一个int类型的数字
32进制的状态
从从左位左边是高位
右边是第一位
依次给我打印出来
放心啊
这个这个函数是会讲的啊
这个函数是会讲的好
我们来看
比如说这个A七十八七十八
你先打印一下这个十进制的形式
然后你再给我打印他的二进制形式
来看一下对吧
就是这两行打印啊
这个啊这一句31行就对应的第一条
打印78啊
这个就是当你需要这个这个这个调用这个方法
就是说啊
这个系统知道你可能是要看十进制的形式
他就给你现转成十进制的78显示出来
理解吧
好如果你打印它二进制的形式呢
那就是这个数值
你看这个位数很长对吧
那么你可以自己去拼一下
看他是不是78啊
他还有一个二
他还有一个四
它还有一个八啊
然后他还有一个64啊
加出来之后就是78
能理解吧
那么这就是它的二进制形式啊
在java中都是有符有符号的嘛
所以它最高位是零
代表它是一个非负数啊
再看这个负数负数
我打印它来
就这一句十进制的话
它就是六啊
让人类好理解的方式给你转换出来
但是他计算机里根本不会管这个
他就是二进制在存二进制再用理解吧
好那么它的二进制形式呢
就是底下这个状态怎么理解
我怎么知道这个状态是六
用用我们的规则吗
你看这个状态是不一大前面一大坨一
后面是010啊对吧
前面一大坨一
后面是010
没问题吧
就是它这个形式不就这样吗
啊好但它是32位的
那你转化吧
首先它最高位是一
他最高位是一
代表它是个负数
它是负几呢
怎么算整个状态
你给我取反
所以这一大坨一样
它就变成了一大坨零
最后101
对不对
这是这个状态取反
然后你再把这个取反的数值再加个一
你加一是从底部加加进位上去的
所以一大坨0110是它负的数值
那这不就是六吗
所以它是六理解吗
大家自己去可以打印自己想打印的任何负数啊
我这里只是提供了一个例子对吧
你可以去尝试任何复数
五也行
八也行
九也行
自己去试都是这样的约束的是吧
好这样的话我就把这个六给打印出来了
然后我们再看你看这个
我定义了一个变量诶
这是啥玩意儿
怎么0B开头
后面你可以用这种方式直接定义二进制
你可以这加好多零
只要不超过零
B后面这个位数不超过32的就可以啊
0B后面这个东西不超过32的就可以
那么相当于我就直接写二进制的形式
是这个意思吧
对就这个意思啊
你前面添再多零没用
你就可以写的100110就行了
这样的话就直接它就会得到一个整形的数字
他这个就是78啊
就是78
你看我们78的状态
后面不是100110吗
对吧
你看我后面这也是100110对吧
我直接可以直接这样去定义二进制的形式
把这个变量定义出来
所以你看这个打印C之前是哪一段
就这个啊
这就对应了我们的打印40行
四十四十一行跟42行的打印就这两行
你看这个数值是多少
78
我是直接拿二进制写出来
它是可以这么定义的啊
然后打印它的二进制
那就是这个样这个样子嘛对吧
那你在你在前面加很多零也一样
那就是无效的
你就加这么多零
其实它不会对数值有贡献
它依然是这个对吧
但你这来个一他就不一样了
那可能就很大了对吧
因为你这个一就不知道是二的几次方了
很大了
对不对
它就会变看到了吗
它就会变变成2126了
对不对
你看它的二进制形式也会把这个一加上对吧
所以这个就跟大家提醒一点
你需要多少位
你就写多少位就行了啊
这是二进制的定义
好的
那么扯到这个呢
我们就已经209
那再扯一个非常重要的概念
就是16进制也可以直接写
这个是啥意思
好我们知道啊
16进制
16进制
比如说我写个二进制形式
我们知道这一共是八位对吧
这一共是八倍
它的二进制形式已经写出来了
这个四位啊
它是不是可以表示0~15
这个也是四位啊
他是不是依然可以表示0~15啊
好的那我们现在来说了
我们现在说什么呢
0000我就认为是16进制里的零
0001我就认为是16进制里的一
然后看这个零啊
1000我就认为是16进制里的八啊
然后1001我就认为是16进制里的九
这个字符
再往下1010我就认为是A啊
拿A代替
那么同样
011拿B代替
100拿C代替幺幺
零幺拿D代替
110拿E代替1111拿F代替理解吗
所以这个八进八位二进制的形式
你写成这个样子
就等同于我们姑且认为它是0B0110
01112进制形式对吧
它就等同于什么呢
0X开头这个0X代表我接下来是16进制的
这是哪个状态
就是六
这是哪个状态
这是七好
我就认为这个二进制形式的变状态
用16进制表示就是0X67
那如果是这样呢
那这个状态又是什么呢
这个状态它就是0X6F理解了吧啊啊
那这个状态是什么呢
这个状态就现在这个状态是什么呢
那就是这个状态我就认为是0X6
理解吧
所以16进制就是说每四位哎
你也别写那么多了
你就一个字符代替你
既然从0000~111
一共16种
不是一共16种吗
对吧
一共16种
我就给你用16进制字符
0~9加A到F这一共16个对吧
你的任何一个状态
都可以被我16进制的一个字符代替
这就是16进制的定义
来我们看一下
比如说
比如说
0X4E是哪个状态
首先它是个16进制
四对应的16进制里是谁
16进制里的四对应二进制是谁
是这个状态能理解吗
啊不好意思
这个
是这个对吧
这就是四所所进行的对应
那么E是谁呢
1110
这就是对应的是一
所以4E是谁呢
就是八位
0X4E它就代表这个状态拼起来的
能理解吧
这是78
所以你看你也可以直接拿16进制拼出一个数
你打印它它是78
这是在这是关于D的打印对吧
在你看在打印D之前
是不是就这两行啊
是不是这两行啊对吧
所以呢这个这个第49行打印出来
就是78
你打印它的二进制形式
就是78的二进制形式
只不过他用16进制表示
这四位被我变成了一下
四位被我变成了四
之前不用管了
哎这就是26进制形式定义出来啊
可以打印对吧
可以打印好的
这个大家函数可以自己去玩啊
在计算机里面都是这种二进制的表达啊
这个啊不不不再多说了啊
其实还有很多东西没说
下面接着说是吧啊
好然后我们再看这个
我们说这个下面讲常见的位运算是吧
常见的位运算
在常见常见的位运算之前
我们可以把这个相反数讲了啊
因为这个代码中它是有这个相反数的相反数啊
或者说取反以及相反数的概念啥呢
就是任何一个状态在这个计算机里会直接取反
比如一个状态是吧
取反这个符号就是所有状态都零变一一变零
这个东西取反就是11010000啊
取反我们来看一下
比如说我们先打印一下刚才定义的AA是谁呢
A就是这个78是吧
A就是这个78关于E的打印证是吧
关于E的打印证
你看我先打印了这个A
第53行就对应的是这啊
第五三行对应的是这
然后再打印A的二进制
是不是他对
然后就直接挂了一个取反符号
是位运算里面的取反
它打印出来
你会发现上面这个状态跟底下这个状态
每一位都不一样
这就是取反啊
这就是取反好
那么怎么得到-78呢
就是78
我怎么得到它它的这个相反数呢
取反之后再加一就是它的相反数啊
这任何数都是这样的
取反之后再加一就是它的相反数
你可以去各种事对吧
比如说这个E它就是A取反之后加一
我们打印出来的E是多少呢
它就是-78啊
然后我们在打印E的状态
就是这个状态其实就是-78的状态
你可以自己去验证是吧
这就是相反数
所以相反数就是一个数
原来的数取反加一
哪怕原来的数是负
它能变成正
原来是正
它能变成负
都是这个都是这个变法
比如说你你来个比如说我们举个例子
比如说你来个17
17有一个二进制形式对吧
你怎么得到负时期的状态好
就是他自己取反
然后再加个一就得到-17的状态啊
啊对负时期的状态
那你从-17怎么得到正时期呢
也一样
你的这个状态先取反
再加个一就变回去了啊
就得到自己相反数
就是取反加一就可以了
十进制也可以
你十进制里面就直接写个减号就行了对吧
A等
就比如说这个我有一个数A对吧
我有个数A他可能是某个数值
那么得到它的这个另外它的相反数怎么得到呢
你就直接写负A就行了
你也能怎么写呢
你也能这么写
A取反
然后加一
这就是这个这俩是等效的啊
这俩是等效的好为什么要提这个话题
因为对于有符号整数来说
有一个数非常的特殊
就是负数的最小值
它是转化不出来它的相反数的啥意思
比如说我们再举个例子
还是我们用四位来表示二进制
我们用四位来表示二进制
我们知道你这个四位你是从-8~-1
能表示一下
以及从0~7表示这些数字的
对不对
那么除了这个八之外
每个数都有相反数对吧
你看你从-7~-1
-7~-1
你完全可以转化成一个相反数
它是有对应的
对不对
从0~70的相反数就是零
零的相反数就是零
它不用找谁对应
那么1~7呢你也能找到-7~-1的对应
唯独这个八你是转不过去的
我们这是四位的情况
你32位的情况跟64位的情况
他都转不过去啊
他都转不过去
为了让大家理解这一点
我们看一下这个打印
比如说有一个数叫整数最小值
我们打印这个数是什么
打印它的二进制形式
在这
F首先这个数啊是负的
负的二的30一次方
那么它的二进制形式就是底下这个状态
就底下这个状态啊
对应第63行打印对吧
然后看64行
我写了一个负F还是自己他是转不过去的对吧
他是转不过去的
那打印这个负F的二进制状态
他也是自己理解吗
哪怕我用取反之后再加一打印
它的数值也是过不去的
然后他取反加一它的二进制形式也跟自己一样
也就是说这个有符号整数最小的那个负数
这是四位的情况
你可以把它推广到32位和64位对吧
有符号整数最小的那个负数是转转绝对值
转它的相反数是转不过去的
为什么
那要看八它的状态是什么
八状态是啥
有符号
整数的话
首先它是个负数
其次你给它转成正数的形式
1000转成正数的形式之后
再给他减个10111
然后再取反1000哦
八就是1000
这个状态好
我们这是硬给它取相反数的话
会发生啥
你看啊
1000
我就让他硬取反
要得到的相反数0111
然后再加个一
它的状态是啥
还是1000哎
这就是他为什么转不过去
这就是他为什么转不过去
理解吗
就是你面对这个状态
他取反之后再加一
他跟自己原来一样
所以转不过去
你的正数那边也没有那么大的数跟它对应
理解吧
这是复数相反数
他得不到的最最小的那个负数的
相反数是得不到的啊
这一点呢就跟大家单独的说明一下
我也加了打印对吧
我也加了打印好
那么关于相反数呢
我们其实就讲完了
而且也讲了整数最小值相反数的特殊性
它取绝对值还是自己对吧好的
那么我们接下来干什么呢
就要了解为运算了
我们已经了解了取反运算对吧
我们已经了解了取反运算
那么剩下的这些都是未运算
我们依次解释一下
首先或运算
我们来看一下货
比如说我定义了两个状态
你不用管它数值是啥不重要
关键是了解未运算是什么规则对吧
你看这个状态上边是0010001010
下面这个是0001100好
所谓的或运算就是每一位只要有一个有一
每一位只要有一个有一就这个一就都能留下来
所以我们来看
第72行啊
其实就对应了现在这个打印
为什么即或上H是这个状态呢
从最低位上来说
咱俩都是零
没有一啊
所以这个位置是零
但是从从从从第一位了
这是第零位对吧
这个是第零位
下面是第一位
一跟零相遇
一留下来
下面零跟一相遇
一会留下来
在下面一跟一相遇
一也会留下来
这就是货逻辑
所以每一位上只要有一个有一
它就会留下来
这就是货
那么与运算呢就只有一个位上都是一
咱俩在与的时候
只有位上都是一才能留下来
这就是为什么
与运算得到的状态是只有一个位置上
有一就这一位
因为只有这一编程
咱俩都有意义
对吧好
那什么叫做异或呢
异或就是每一位咱俩相同的话就是零
咱俩不同的话就是一看就这个这个状态
为什么
因为这两位我是零一
而H变量是一零不一样
所以是一一状态
而剩下的V都一样
所以是这个状态看似很简单是吧
实际上玩法非常的多啊
计算机可以说就是被这些未运算包裹起来的
一个强大的计算能力的工具啊
它有它后面有啥用
我们会讲到的玩法可多了是吧
好好
那就是就是所谓的这个或与和异或啊
就讲完了
所以状态上你就可以直接直观的看到
当然你们也可以自己去写这样的测试对吧
你也可以自己去写这样的测试
然后我们要扯一个东西
就是后面取反
大家已经明白了
已经打印过了嘛对吧
这些先留着不讲
我们看一下
注意啊
一个竖线
一个与符号
这是未运算的或和与啊
这是未运算的
或和与还和这个
我们知道这两个竖线就是逻辑上的货对吧
A或B两个条件
A或B两个条件会这么连接对吧
这两个呢是逻辑上的与对不对
这个大家都接触过
只要写过代码都知道好
它是有区别的
什么区别呢
我们来看一下啊
就比如说啊比如说我有一个布尔类型的变量
比如说它叫T对吧
我要是这么写
如果A它返回true的话
后面它是不会进行计算了
他会直接跳过
因为这是逻辑或它的穿透性
是只有你前面都是false
它会一直穿透下去
如果你但凡是某一步已经是true了
后面连执行都不会执行
就直接能得到这个布尔类型的值
它是true了
能理解吗
就比如你再多连接
你再多的连接
它的穿透性是你一路都是false
它才会一路穿透下去
直到遇到某个位置是true
它会直接停止这个变量的
这个也就它的赋值也就完成了
对不对
后面再有的东西它不会执行的
它连碰都不会碰的啊
所以它的穿透性是一路false
它就会一路穿透下去
但凡是你遇到了true
它就会停止
这就是逻辑里面的那逻辑里面的语也是一样的
比如说一个布尔类型的值
遇上必如果你这个地方是false
它就不会再往下穿透了
他后面连执行都不会执行
因为它已经能够得到它是false了
你是与运算吗
有一个是false就是false吗
对吧
所以如果是一大堆的连接
它的穿透性是你一路是true才会往下穿透下去
但凡是你遇到一个不是处是false的
后面连执行都是不会看的
代码根本不会执行到后面去
这就叫穿透性对吧
但是未运算理念他不会这么干的一个布尔类型
然后可能A这个变量也是布尔类型
你要写一个未运算的
或它就不一样了
虽然它是布尔类型
那它也有微信息
对不对
他也是布尔类型
它一样会有微信息
如果你是写或运算的话
我告诉你两个是一定都会执行的
因为他必须确定这是啥状态
他也确定这是啥状态
然后取货理解吗
好为了验证这一点
我们看底下的扣的就行了
大家看我写两个函数
只要你进入了这个函数就会打印
进入了return true函数
它就会return一个true
看到了吧
只要你进入这个函数
它就会打印
进入了return false函数会return一个false
那么我们来看这一句
如果我就是写一个布尔类型的
叫test1return true和上return false
但它是未运算的活
它是未运算的货
我们看会打印什么
test1测试开始这一句
然后在真正测测完了第85行
test1测试结果是它是true
因为这两个有一个是true
它最后结果就是true
但在这中间发生了什么呢
你会发现它既进入了return true函数
也进入了return false函数
说明啥一定都执行了
左右两侧一定都是去执行了的
对不对
我们再看test2test2测试开始
在这test2测试开始
如果你是逻辑上
用或两个两个竖线表示逻辑或去连接的话
test2的结果也是true
但是你会发现它只进入了左半部分的函数
因为左半部分已经是true了
他就会后面完全不执行
所以你根本连进入这个函数
连调查的机会都没有理解吗
所以我们看只打印了一个return true的函数
能理解吧
这是一定要区分逻未运算的货跟逻辑货啊
它是不一样的
同样道理与运算也是一样
我第一个return false已经return false了
你又是与运算
按道理是可以停了对吧
但不停为什么
因为它是未运算的与运算位运算的与
所以它两边一定会都执行的
比如说test3开始之后
他进入了return false
也会进入return true
他一定都会去执行
但你test4就不一样了
你拿的是什么连接
你拿的是逻辑逻辑语
如果一旦return false
后面是不会执行的
所以test4测试开始的时候
test4测试开始了
它就会只进入return false
函数就会得到了
然后它就停了
理解吗啊
这个就是我们说的逻辑谓的语和
逻辑的与和或它是有区别的啊
主要大家区别在于穿透性上对吧
好的
相反数也讲了整数最小值的特殊性也讲了
转不过去
该讲一个非常重要的内容了
就是为什么这么设计二进制对吧
为啥这么设计二进制
说白了就一句话
他是为了让加法逻辑是一套逻辑
没有条件转移
他说老师你说点人话吧
好我跟你说人话来看
还是回到我们那个例子
假设一个二进制啊
假设一个二进制是四位的
好吧
我们看那你比如说你在做加法的时候
你是怎么把两个数加起来的呢
我们不妨假设比如说是啊
3+4吧
啊比如说呃不好
3+4不好
3+5吧
3+5好
四位的话
三是谁
这是三对不对
五是谁
这是五对吧
在执行3+5的时候
你怎么加
像我们小学时候做加法一样
两个一相遇有一个进位
这是零
这两个一相遇有一个进位
这是零
这两个一相遇有一个进位
这是零啊
这溢出了是吧
加完之后溢出了啊
那咱们换个例子啊
就因为因为你这个最多表示正数到七吗
你3+51出了是吧
那一出了
就是你可以认为最后结果肯定是不对的
因为他他表示不了嘛
那我们就写一个啊啊比如说比如说嗯
3+4不不好嗯
比如这个吧啊比如这个这是谁呢
这是1+2啊
1+31加三
两个一相加有一个进位
这是零两个一相加
有一个进位
这是0100100是谁
是四
1+3
正好等于四对吧
好
我们再举个例子
别比比如说位数长一点是吧
加这个
这两项加怎么加
那么我们不用管它是几啊
告展给你展示
最后加出来能对就行了
1+0
这是11+1
这有一个进位
这是01+1
这有一个进位
这是零三个一相加
有一个进位
这是一三个一相加
有一个进位
这是一
然后0+0加一一好
这两个二进制的形式
它首先都是非负的对吧
它的加法逻辑是不是特别确定
你从低位一直加上去
有进位就一直进位下去嘛
就加嘛对吧
好
这至此我们就展示了
你看你这个加法逻辑在正数
或者说在非负数加非负数的情况下
它的逻辑是高度统一的
对不对
好的
那你如果是个正数加负数或者负数加正数呢
我们举个例子
比如说
附加二
好五的二进制是谁
核心点来了
这样加的时候依然遵循那套逻辑
最后能整对你敢信啊
没问题的
就是我们我们来依次来还原一下
首先五的二进制
我们再次强调怎么算它正数是谁
正数正数多少之后它减一是谁
0100再把这个状态取反
是谁
这是五啊
我们验证一下它是个负的
那它负极呢他自己的状态取反0100
再加个一啊
原来是0101啊
确实是五对吧
好五的状态真的是他10112是谁
这是二
所以-5+-2也这么加
一跟零相遇得到一一跟一相遇有一个进位
这是零
零跟零再加一
这是一
1+0
这是一
那么这是几
首先它最高位是个一
是个负数
那它是负几呢
把这个状态取反
再加一二负三
居然不需要条件转移
大家能懂吗
居然不需要条件转移
大家能懂吗
好我们再举个例子
-5+7再来展示一下-5+7
刚才是五是啥来着
就重新写一遍吧
这个我忘了0101是正午对吧
减个10100
然后再取反10111
011是五啊
1011是五
七是谁
0111-5+7得到的是二对吧
-5+7得到的是二
你看能不能对上1+1有一个进位
这是01+1
再加一有一个进位
这是11+1有一个进位
这是01+1
有一个进位
这是零
然后我们就可以认为在四位的情况下
有一个E出位丢失了
能理解吗
他丢了就认为没了
这是几二
大家理解为什么要这么设计负数了吗
就是为了让真正做加法的时候啊
不管你是非负加非负还是负数加非负还是非负
加负数还是负数
加负数
但负数加负数的例子我们没有展示
大家自己可以去试一下
依然对的
这四个数四种情况
你是不需要定制你的加法逻辑的
你不管是什么状态
都走同样一套逻辑
最后能把你答案给你整对
这是它最精妙的地方啊
这是它最精妙的地方
同时我们也意识到
在二进制中
他可能是经常溢出的
比如说我们刚才这个-5+7的这个例子
最后有一个溢出位
我就直接丢弃了
但最后的结果是对的
这提醒我们什么
就是你在用加法
用一些乘法
用一些
比如说用减法
用这些数算术运算的时候
你必须自己保证
A加B它天然的本来的结果就是不溢出的
然后计算机它就能给你算对
你必须天然的保证你调用这些符号的时候
得到的结果它就是不溢出的
你必须自己保证这件事
计算机它会给你正确的结果
但你如果自己不保证它会不会溢出
那计算机他根本就不会管你
因为它就按照它背后的一整套逻辑来算理解吗
所以如果溢出了计算机
没有权没有责任去检查你自己
活该懂这个意思吗
我们本来我们要自己去警惕一出
就是这个道理在计算机里可能是经常溢出的
那你要保证在业务上你真的不会溢出
那计算机即便他在计算的过程中发生了一出
最后的结果
他也能给你整对
就是为了这个才把负数的设计搞得这么扭曲
他就是为了让加运算快
大家想象一下
我如果要是不同的情况
我加法逻辑走一个情况
一的定制再走一个情况
二的定制再走一个情况
三的定制再找一个情况
四的定制
如果他有逻辑跳转的话
你是不是慢了
而你整个它就是一套逻辑呢
连情况跳转也没有
那么这个加法逻辑是不是整的飞快啊
正是为了达到这个目的
才把负数设计成这么扭曲的样子
他就是为了在真实做一些运算的时候
你就不用转化了
直接来
这就是他的理由
为什么要这么设计
二进制理解吗
好的同学还问了老师
那为啥加法逻辑如此重要呢
因为我们后面的课会讲
怎么样用位运算实现加减乘除
加减乘除
这些东西在计算机里面根本没有
专属于自己的逻辑单元
只有未运算的单元
乘除都是由加法这个东西高效地拼出来的
就是你你会认为城市若干个加法一直掉吗
它比这个高效的多
但他最终还是加法拼出来的
剩下的算术运算
所以他必须保证加法逻辑很快
他只要把加法逻辑搞得快快的
底下的这些运算它都会快起来的
我们在后面的课
怎么样用位运算实现算术运算的时候
会非常详细的讲述它怎么实现的
总而言之
把加法搞快是能够换来底层性能的巨大提升
理解吧啊所以加法逻辑很重要啊
后面的课会讲怎么实现啊
会讲怎么实现好
所以呢关于这个关于溢出呢
就大家要自己确保调用所得的结果
它不会溢出对吧
一定是自己确保的
计算机不会给你检查溢出了
你活该是吧
这关于溢出我们也讲了
还有就是未运算的玩法很多
特别是异或运算
特别是异或运算我们都没怎么讲
展示异或运算就展示了一下
哎呀相同为零
不同为一是吧
给你打印了一下
但其实异或运算与之相关的算法设计非常的多
我们后面的课都会详述
以及我们后面会讲如何用位运算实现加减乘除
后面的课都会详解好的
这节课还剩一个东西啊
准确来说还剩几若干两三个吧啊我们来看
一个数字我告诉你哦
没有讲左移和右移是吧
嗯没有讲左移和右移是吧啊
就是关于左移和右移
我们来展示一下嘛对吧
这是左移
比如说这个I状态
在这I状态
这是他的二进制形式对吧
我左移移位啥意思
哦在这啊
在这这个这个是I状态是吧
因为这是左移嘛
在之前打印这个第98行
对应的是这个二进制是吧
左移一位指的是我整体状态都向左移动移位
你比如说你看这一段这个它就被移到哪儿了
移到了这儿
那你左移的话
你右边就会空出来对吧
拿谁补
拿零补能理解吗
拿零补
那我I要左移两位呢
那这个状态啊
整体它就被移动到了
这它就被移动到了这儿
右边拿谁补呢
拿零补看到了吗
那I向左移动三位
那这个这这这这这这这个位置它就被移动到了
这后面拿谁补呢
拿零补啊
都是这个意思
这就是左移啊
整个状态往左移动
当然它会移着移着它会移出去是吧
或者说移到你把这个一移到最高位置
它就变成负的了是吧
你再移就可能没了是吧
这就是左移V上理解就行好
那么右移呢它就分为这两个符号是不一样的
这个这两个符号啊
那对于非负数来说
它效果是一样的
右移比如说啊我们来展示一下右移
你比如这个状态是A对吧
对应第104行的打印
对应第104行的打印
这个状态是I我又以两位
你看啊
你这个状态又一两位
那这两位就被干掉了对吧
你这个110是不是就移动到这了
它整体都会往右移动
那你左边空出来的是啥
你左边空出来的
拿谁补啊
拿零来补啊
拿零来补
对于非负数来说
这个符号和底下三个叉的它效果是一样的
都是拿零来补
比如说这个三个叉的右移完了之后
他也是整体状态都向右移动
然后最右边两位状态给干没了
左边空出来了呢
拿零来补
对于非对于负数来说
它就不一样了
比如说我们这个状态
我们这个状态这个就代表用符号位来补
在这大家看这个状态
它就是G啊
对应110行的打印
对应110行的打印
我又以两位
那么整体的状态也是最右边这两位就被干没了
你这个整体的这个状态就被移到哪儿呢
就被移动到了这啊
那你左边拿谁补呢
拿它的符号位来补
所以左边补出两个
一来这个就是这个的含义
就是他用符号位来补位
左边拿符号位来补位
所以非负数他这两个东西是一样的
一个是你就算是用符号位来补位
你符号位是零对吧
三个就是我不管你符号位是啥
一律拿零来补位
就底下这个状态
你看整个这个状态啊
它向右移动两位
来到这最右侧的这两位给干没了啊
给干没了
那我右侧
那么左侧拿谁来补呢
拿零来补
这就是这个符
两个叉的符号和三个叉的右翼符号的区别
两个叉的就是你拿符号位来填空缺
左边的空缺拿符号位来填
这个就是我不管你是正还是负
你左边的空缺一律拿零来填
这就是左移和右移啊
左移和右移就都给大家未运算就是告一段落
就这些啊
同时还要给大家提醒
就是对于非负数来说
左移一位等同于乘以二
左移两位等同于乘以四
左移三位等同于乘以八
左移I位等同于乘以二的A次方
当然是有这个规律的啊
因为他这个位数往上提了
就相当于乘了二
他在往上提嘛
一样的对吧
那对于非负数来说
右移一位就等同于除以二
右移两位就等同于除以四
右移三位就等同于除以八
又一位就等同于除以二的次方
只对非负数有效理解吧
啊负数是没有这个规律的
所以我们来看一下
我们随便给他一个非负数十打印
它自己十对吧
这是十打印出来了
左移一位等同于乘二
所以这是20
左移两位等同于乘以四
所以这是40
左移三位等同于乘以八
所以这是80啊
有这个规律对吧
右移一位等同于除二
所以这是五
又以两位等同于除四
所以10÷4是二又一
三位等同于除以八
所以10÷8就变成了一啊
所以关于非负数来说
它左移就代表它在不停的乘二啊
它效果是一样的
它右移就代表它不停的除二
只对非负数有这个效果好
大体上就讲完了
我们所有的代码都给大家展示了
还剩一个函数大
怎么你到底是怎么打印二进制的对吧
你到底是怎么打印二进制的
好我们来展示一下
比如说啊我们有一个状态number他什么状态呢
01101100
你打印吧
怎么打印
我们标好
这是第零位
这是第一位
这是第二位
这是第三位
这是第四位
这是第五位
这是第六位
是第七位
我怎么知道他第七位有第七位是零还是一呢
那你就让member与上一个
向左移动七位的状态
看看它是多少
啥意思
我们一点点说member不是这个状态吗
对吧
一是谁
一是他
他向左移动七位是在哪
移动一位
两位
三位
四位
五位
六位七位
所以一向左移动七位
它就变成这个状态
好那么member与上一向左移动七位
他得到谁零啊
因为我最高
因为我第七位上是零
你这是一
咱俩结合完了之后是零吧
然后每一位咱俩就没有共同出现一的时候了
所以member与上一向左移动七位
如果是零的话
你就打印零就好了
好我们再看
那我怎么确定我的第六位上是什么状态呢
那就member与上一向左移动六位
一向左移动六位是谁啊
一向左移动六位是他
一向左移动六位是这个状态
所以member与上一向左移动六位是哪个状态
这个状态
它等于零吗
它不等于零
它等于几
它等于二的六次方
对不对
十进制里的二的六次方
对不对哦
所以我与完了之后
如果不等于零
那你接下来就打印一呗
你先打印零了
再打印一呗
然后你每次不要这么打印不就行了吗
member与上一向左移动五位
得到二的五次方不是零
所以再打印个一
一与上向左移动四位是零
再打印个零一项
再与上一向左移动三位
得到不是零
再打印一
就是利用这种方式
把一个member的二进制形式依次打印出来的
就是这个函数的意思
就是这个函数的意思
我们来看一下是很简单的一个函数
你看这是这个这个数值A是吧
我们把它改成member
把它改成member
就是member对吧
然后member与上一向左移动31位
啥意思
你整数啊
整数一共是32位嘛
所以他的胃是从第零位
第一位
第二位一直到第31位嘛
这一共32位嘛对吧
你这个你有一个member
你的每一位的状态
你的美
你的每一位的状态都在这里面放着
你一先来到31位
后面都是零
你与一下
如果它不等于零
那就是一状态
如果它等于零
那就是零状态对吧
所以你就以每次不断地与就行了
一向左就是先看一下member与上
一向左移动31位等于零
就打印零不等于零呢
就打印一在member与上一向左移动30位等于零
就打印零不等于零呢就打印一
这样的话
你就把整个一个数字32
静止的状态就都打印了
请注意啊
这个注释说的是什么
就有有的同学认为你比如说你member他是这个状态
还是这个状态
这是第零位
这是第一位
是第二位
是第三位对吧
然后我想知道第二位的状态是啥
有同学可能会这么写
member与上一向左移动两位
如果等于一
我就打印一
否则我就打印
零这么写是不对的
为啥一语上啊
member与上一向左移动两位得到是啥
他与完了之后得到的是这个状态
他是一吗
他不是
他可是二的二次方
它可是个四啊
懂吗
所以你不能拿它等于一来判断
你只能认为它是等于等于零还是不等于零
它等于零就一定是零
否则它就是一状态理解吧
就是不能这样写
等于一
那是不对的
因为这两个东西与完之后很可能它是这个状态
而这个状态它是不等于一的
它等于二的某次方理解吧
你用这
你用它是否等于一个二的某次方
来确定这一类有没有一懂我说的意思吗
对吧
就是它与完了之后可能不是单纯
你这看着是一它得到的结果就是一没那回事儿
人家得到的是四这个数值啊
是用状态来看
然后把它对应成十进制的来理解理解吧
啊好的
这个就属于我们我做的一个题型啊
其实就是这个意思啊
就是这个意思
还有最后一个点
我们本文件都是按照整形来举例的
对于long类型来说是同理的
但是你要是member与上一向左移动48位
这是不对的
因为你这么写的时候
一它就是一个整数
而整数是没有48位的
所以你一向左移动48位以上
判断member第48位是否有一
这样写法不对
这个一他早就溢出了
因为一个一你不给它加任何注释
或者说设定它就是一个整形的
而整形它只有32位的
所以这么写不对
那怎么写
Member
如果是long类型
他想确定自己48位上有一还是没一
你需要member与上1L向左移动48位
这个1L它是一个long类型
它是有64位的
所以你想用long类型来提取的话
不要忘了你不能轻易的让一向左移动48位
你要定义1L向左移动48位才对
因为因为原始的一他们根本没有64位
你移动48位就错了
理解吧
啊讲了好多是吧
但是我觉得讲的是不是弱
戳中了很多朋友
这个若干认识上的一些误区是吧
我们再次强调未运算的玩法很多很多
以及用位运算如何实现加减乘除
还有一个概念叫用位运算
怎么实现位图
这些都是非常重要的基础
我们后面的课一定都会讲到啊
可以自己多打印
多理解啊

被折叠的 条评论
为什么被折叠?



