00:00
那接着呢,我们来看一下后边这个运算符,哎,这个是我们讲的第五个了,这那叫未运算符,我们在刚开始说运算符的时候提过,说这个位运算符呢,我们用的比较少啊,呃,这个运算符呢,总共咱们说的算是六种未运算后运算符,后面呢还有一个三元运算符,整个呢,这六大类里边呢,这个未运算符用的确实频率比较低,呃,这个对大家的要求呢,就是能看得懂啊,一会呢,我会讲一讲这里边这个运算符具体是什么意思哈,大家能知道它具体什么意思就可以了。呃,等后边呢,我们自己开发的时候呢,其实用的比较少,另外一方面呢,呃,咱们讲后后期的这些内容也会带着大家呢去看一看源码,看源码的时候呢,有时候会遇到哎这样的一些符号,比如说无符号右移啊,比如说呢,像左移了这个你能知道它是什么意思,哎就可以了,所以关于位算符呢,对大家要求呢并不高。好,那我们呢,先来说一说这个微运酸氟它是怎么使用的啊,涉及到的符号呢,一共有这样的一些。
01:04
这呢叫做左移,这呢叫右移,这呢叫无符号右移,哎,这个叫与或异或还有一个取反,其中呢这三个符号我们在前边一个讲逻辑运算符的时候呢见过。啊,首先呢,大家需要先明确出来,那回头呢,你看到这个符号,它到底是逻辑还是应该叫为。取决于,哎,对,取决于它操作的数据类型,那如果呢,我们这个符号呢,左右呢,都是布尔型的,那是什么呀。逻辑的对,你又想判断说前面是个波尔行,然后这呢有个与哎,后面有个波尔行,就是一个逻辑的啊,而且呢,结果也是个多句,呃,也是个波尔形,那我们这儿呢,操作的啊,就是这里边的这些运算符,操作的呢,首先都还是数值啊。哎,都是数值类型的结果呢,也是一个数值。啊,通过这个呢,你去区分它到底是哪种符号啊,这是第一个,然后的话呢,我们下边呢,一个一个来说一说,首先呢,涉及到这个叫左移右移和无号右移,嗯,首先呢就是数值。
02:11
啊,而且呢,还都是整数啊,都是整数,咱们做左右移,没有说见过一个小数浮点型的,然后左右移的啊,那么像这个三呢,我们叫像左移两位,结果呢,看到是12。啊,这个三呢,又一位呢,结果是一,怎么得出来这个数呢,我们还是理解它这个过程就OK了,哎,所以这块呢,我们这个画这个图不是画个图了啊,这个我们这个通过这个图示的方式啊,来给大家去展示一下。那这块的话呢,我们自然而然的呢,也把这个数呢,就比如说都看成是一个这个in的形了啊,你要是常量的,那就是in形,或者你定义变量呢,也用in的形也OK,所以这块呢,我们这样子做啊,我呢先写一个计算器。先进来,进来以后呢,我这来一个,哎,整形的啊,以整印的形为例,咱们整一个数,比如说我就随便起一个数了啊二一。
03:08
知道了21的话呢。长这样,我把这个呢截一下。好,这个就放到这了,是我们十进制的21。好,那么这个21呢,是一个整数呢,我们可以考虑对它进行左右移的运算,现在给它左移两位,哎,左移两位呢,就是针对于它底层的二进制来讲,在二进制它这个数值的基础之上呢,向左移移两位,那移两位呢,就意味着左边呢出去两。哎,左边出去啊,右边呢,是不是需要补两个呀,空出来了啊,那这时候拿什么补啊,对,那不是拿零就是拿一了,那这呢,我们说都是拿零补的,不管正数负数都是拿零补,行,那补完以后呢,其实我们关心的是这个数现在变成几了。
04:03
对吧,哎,变成几了,那这时候我们来分析一下啊,像一开始的时候这个数,像这呢,咱们昨天也讲过二进制转十进,呃十进制了,它这个一的对应的是不是2.0次幂啊,这个呢,对应的二的二次幂啊,三次幂,这是二的四次幂吧,对,其他都是零,不用管了,我把这几个数加起来就是21。对,那现在呢,我向左移两位以后,你想想啊,原来是2.04米的位置,现在变成了2.24米了,然后对应的你这个呢,三二十四次幂呗,这是五,这是不是二的六次幂,那我要计算这个数是几,是不是也是加一下就行,哎,加一下你会发现实际上就相当于在这个的基础之上。啊,对,这这这也是一个加的运算,是不是相当于乘了一个二的二次幂啊对,乘了一个二的二次幂,哎,那行,这是我们向左移两位哈,这是相当于是我们这个数是21乘以四,是不是就是这个结果呀。
05:08
对吧,嗯,那我要是向左移三位呢。二是不是就得在这个基础上再乘以一个二,相当于是在这个地方是不是乘以2.34米了啊,那那这个规律大概能出来不。就是每向左移一位,相当于呢,在原来这个数的基础之上呢,乘了一个二。因为你所有的位是不是都往高处进了一个二啊,哎,对啊,这就相当于是一个小的一个规律了啊,或者是一个结论啊,那这块呢,咱们这个数呢,可以通过代码的方式呢,进行一个测试啊,Z03我们新建一个Java文件啊,未运算符就写成了bit了,这样啊。Ctrl a ctrl v保存。
06:09
哎,这运算符之五。哎,这个呢,我们叫位运算符,哎这呢,大家就是作为一个了解就可以啊。CTRLS一下,好,那我们来演示一下啊,刚才呢,我们说到这个事了,那我int一个I,这个I呢,我刚才是一个21。哎,然后呢,我们这里边儿,哎,我就直接写到这吧。嗯,让这个I呢去左移两位,哎,得到这个结果啊,这个我们写到后边啊,这个I呢左移两位,哎,其实我这个小括号呢,呃,我不加也没事啊。嗯,这样也可以,这个优先级呢会高一些,哎,我们讲了预算符以后呢,统一的来说一下这个优先级的问题啊,保存来测试这C。
07:07
A test奖章啊。哎,这时候我们报错了。说这个左移操作类型。那这时候还必须让我加上啊。他他就得加上了,哎,再来。编译啊,这个才能通过啊,那说明什么呢?就是这个时候呢,它的有歧义了啊,就是我们这个左移呢,和我们这个连接符呢,它俩的优先级在同一级上了,所以它就从左往右走了,从左往右走,这就成了个字符串啊,字符串呢不可以左移,所以它报错了,那那这呢,咱们就给它加上啊,加上保险一点就是表示呢,它先预算好,编译通过以后呢,我们来执行一下。啊,结果呢是84,那这就是咱们所说的21呢,相当于是乘了个四,那就是84啊,那如果我要再往左移的话呢。
08:00
那就再接着去乘以一个二啊对,我这往做一变成三位了啊哎,保存再来。哎,相当于呢,在21的基础上呢,我们移了三位,是相当于移了二的三次方,对,相当于乘了个八,哎,这不就是168嘛。对,哎,这个每向左移位呢,乘以二这个事呢,大家现在能理解吧,哎,能行,那问一句,这个往左移,每次移乘以二,每次移乘二有没有一个限度啊。对它有一个限度啊,你看啊,这是咱们本身的这个是21了,那你想想我要是我移,我移的比较嗨了,我移到这儿了。啊,一到呢,就是我这个最高位呢,诶突然变成是个一了啊,我左边呢,仍然都是拿零去补。哎,哪里补的,那你看我这个数,我这是向左算是移了多少位。
09:06
左一整个呢,一共是32位是吧,这是四位32减这是。这是28 28,咱们这个留着呢,应该是移到27位吧,啊,移到27位啊呃,按照咱们的想法说,我每下左一位呢,就是乘以二,每次乘以二乘以二乘以22,结果到最后那一瞬间的时候呢,崩塌了,这个一下这个数呢,变成了一个负数了,你看是吧,来咱们测试一下,你看看啊。再接着CTRLC。它呢向左移,我们先先移一下26啊。126的话呢,这时候这个最高位其实还是一个零的,这个数呢,会相对比较大一些,你看这个数就很大啊。呃,然后呢,我们以27。哎,127就刚才说的这个事儿啊,变成这个样子了。
10:06
编译运行,你看这时候这个数呢,瞬间就变成了一个非常小的一个数了。对,就变成一个负数了,因为你这时候的最高位呢,出现的是一个一。啊,这其实就咱们这个这个成语里边有一个词特别适合来描述他的啊,物极必反是吧,哎,说的很好啊,或者叫过犹不及啊,都可以啊,就以为呢,特别好特别好,在到的那一瞬间的一下子就跌下来了是吧?啊你像现在这个这个这个咱们国内那个房地产这块王健林啊,当然具体细节咱们不好说了啊嗯,这个也是首付是吧,那那有可能整不好了,一下子可能就就塌下来了啊,变成巨亏了就成了啊,所以他们其实每天都不好啊,还是有钱啊,他其实借了银行很多钱啊,就是他们你看着是有钱,其实这个钱呢,就来回的倒着用了啊。
11:00
对行,那这块呢,我们把这个结论来说一下啊。哎,结论结论呢,就是首先呢,我们这个印呢,操作的都是这个整形的变量啊。哎,操作的都是啊,整形的这个变量啊,或者整形的这个数据吧,就是不一定非得是用变量啊,我这个位置我写成个四也行,四呢就相当于是个敞量也OK啊这是第一个事儿,第二个呢,我们说呢,这个对于这个左移来讲啊,它呢在一定范围内。哎,在一定范围内,然后呢,每向左移一位。每向左移一位。哎,我们说呢,哎,相当于哎乘以二,哎,这我就这样写啊,相当于是乘以二。嗯,那相应的话呢,这是是不是就涉及到一个右翼啊,你要向左乘二了,那右翼是不是就除以二了。
12:04
对的啊,在一定范围内每项右移一位呢,相当于是除以R。哎,每向右。那第一位啊,相当于呢,是除以二。行,这个呢比较好理解啊,那这里边儿还有一个问题呢,就是说负数呢,是不是也是这样的规律,那其实呢,负数也是啊,嗯,那这块呢,比如说我我就这样吧,我就把这个I呢改成是负的21吧,保存看一下。边移变行,你看啊,负二移我们向左移了,向左移的话呢,这不就相当于你也一两倍零乘以四了,这不就负八二十四了,就下边这不也是这样吗。对,就是负的168是吧,这个我们说在一定范围内的时候啊,这样的一个情况,这个呢,属于就是你这个这个过了过了那个限度了啊,所以这个呢,大家去理解一下这个问题。
13:05
啊,这个问题这样呢,说到这以后呢,我们就能提到一个比较老的面试题啊,这个说的不好听的,叫老的面试题,说的好听一点呢,就是叫经典的面试题是吧,那这个面试题这样说的啊,说这个最高效的。最高效的啊,然后呢,让你去计算二乘以八。来问怎么算?最高效的方式是怎么算啊,哎,那就是要么呢是二呢,我们是不是向左移三位是吧?哎或者呢,你写成这个八呢,哎,向左移移位是不是都可以啊。对吧,对,这都行啊,就是你你你回答他也行,回答他也行啊,就这两个呢,咱们就不再区分说,哎,这两个好像好像他是不是就更快一些啊。
14:04
这就不这样说了啊,就他俩呢,是属于同一个数量级这个层面的。那这个大家如果你要接触过数据结构和算法,咱们会拿这个大O去比较是吧,呃,像它俩这都属于这个常数级的,这个这个时间复杂度了就啊对你要是没听过这个概念的,你就就当没说一样哈,哎,这个呢,肯定比我们什么效率比较高呢。二乘以八,那你要么就理解成是八和二相加。或者呢,理解成是两个八相加也行是吧,那那那个效率呢,实际上是要稍微低一些,这个呢,就是最高效的一种方式啊,就是借助了咱们刚才说的这样的一个结论啊,这样的结论啊,行,那么这个右移的话呢,咱们其实刚才没有提哈,这个右移的话呢,我们稍微再多说一句,就是比如说呢,这呢还是一个正的,这是21,那我要是向右移。哎,右移两位。
15:01
哎,用一两位,哎,这个时候呢,你就得需要把这个式子呢,哎,给它往右这块去拽啊。哎,转完以后呢,我们右边就多出来了两位。嗯,那现在呢,左边这个高位呢,就空出来了两位。那这时候问,这时候空出来这两位拿谁去补,哎,这个时候呢,我们就说了,你如果要最高位,原来啊,最高位是零,表示你是个正数啊,你要最高位是零呢,我就拿零补。哎,如果你要是最高位是一的话,就意味着你原来这个数是负数,那就拿一补。啊,那就是比如我这要是一个负21,咱们刚才在代码里边这块写过了啊,我要是负21的话呢,那你往右移的时候呢,那就是哎,就是写两个一,要右移两位这块就是两个一了。行这块,呃,三个,你要一三位,那就填三个一。
16:02
啊,就这样就行啊行,这块我就不多去说这个问题了,那这是左移和右移啊,就是对于这个右移的话呢,稍微有点不同,就是最高位,根据你原来的最高位是一和零,然后相应的哪一或者零去补就行,那么还有一个呢,就提到叫无符号右移。哎,五负二对一是什么意思呢?就不管你原来这个数是正数还是负数。啊,我要是往右移的话呢,哎,都拿零补。这个我们在这写着呢啊。在这写着你看啊哎,被移位呃,二进制就是这个叫右移嘛,这个本身这个式子是在这儿,然后呢,你往右移动以后,高位呢,空出来了,无符号,右呢就是不管你最高位是零还是一,我都拿零补。那言外之意呢,如果我这个数是一个负数的话。我要往右无符号右移一位,这个数是不是瞬间就变成了正数了?哎,对的啊。
17:00
嗯,那那这有什么意义呢?其实呃,像这种我们使用无号右移的话呢,根本就不是想让它实现除以二的操作了。呃,你要是想让它实现除以二,是不是得用这种符号啊?对吧。这个符号是不是我们表示往右移除以二了,对这个呢,你要是个负数,你往右移一下就变成个正数了,这肯定不是除以二了啊,那这个符号干什么用呢?这个后边我们讲那个集合,呃,讲到它的那个,呃,求那个哈希值的时候呢,我们看几层源码,它会有这个符号,呃,现在一两句话给大家说不清楚啊,所以我们就先不讲了,就这呢,后边也是会用到,但是咱们自己写代码的时候呢,基本上不会用。啊行这块呢,我们就只需要知道它是什么意思就可以了啊。
我来说两句