二进制和位运算

好同学们

我们说一下这个二进制和位运算

以及一系列需要注意的点啊

这节课不建议跳过啊

就是他会他一定会戳中某些朋友

这个呃就是学习上的一些没有注意到的东西

尤其是这个第十个为什么这么设计二进制是吧

你可能上学的时候老师就跟你说

记住就行了对吧

那其实它是有非常精妙的理由的啊

好我们一点点来

首先我们先介绍一下二进制和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位就错了

理解吧

啊讲了好多是吧

但是我觉得讲的是不是弱

戳中了很多朋友

这个若干认识上的一些误区是吧

我们再次强调未运算的玩法很多很多

以及用位运算如何实现加减乘除

还有一个概念叫用位运算

怎么实现位图

这些都是非常重要的基础

我们后面的课一定都会讲到啊

可以自己多打印

多理解啊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值