00:00
接着呀,咱们来看下一组的一个指令,下一组指令呢,我们称为呢叫算术运算符,也就是咱们平时常说的这些运算符,比如说加减乘除这个与运算,这个或运算异,或运算取法运算等等,这呢在这呢,我们统称为呢叫做算术指令,那大体上的话呢,分成针对于整形的算术指令和针对于这个浮点型的这个算术指令。那整个呢,三指令的作用是什么呢?就是作用在两个操作数站上的这个数据,让这两个数据呢,做某种特定的运算,比如说呢,做这个加法运算,那把这个运算的结果呢,再重新的压入操作数站。注意这里边还有一个重新压入操作站这样的一个操作,那难道说运算指令通常都是两个这个操作数站上这个数据吗?一般都是这样子的,对吧?当然你回忆一下咱们做的像加减乘除啊,与运算呀或运算呀,这个异货运算啊等等,像这些运算呢,一般咱们都会涉及到两个变量,中间呢,有一个特殊的运算符,对吧?所以一般针对的都是两,当然呢,也有一些特殊情况,比如我们说这种取反的操作,那相当于这叫单目运算符。
01:07
那一会儿咱们也有个例子,关于区法,大家呢,也可以看一下这个它怎么涉及到叫两个操作站,操作数站上那个数据,一会儿咱们有个例子来说行。那么在下边儿呢,针对于我们说BA short char波类型这块的一个说明,咱们在前面呢,已经多次出现过这样的场景,也就是说呢,凡是针对于这四种类型做运算的时候,我们统一的把它们看作是四个字节构成的一个int类型做运算就可以了。这个不用多解释对吧,再下一个呢,提到叫运算时的一个溢出问题,那我们说做算术运算的时候呢,咱们知道做除法这个分母呢,是不能为零的,包括呢,我们要是取模运算,这个模数呢,也不能为零,那一旦要为零怎么办呢?我们说这个结果呢,就是arithme exception。这个咱们前面或者大家开发中呢,咱都知道这样的一个场景,对吧,这呢就不过多的去说了。
02:00
然后再往下的话呢,提到一个运算模式,那两种模式,第一个呢叫向最接近数舍入模式,一个呢叫向零舍入模式,说的直白一点呢,这呢就类似于叫四舍五入的模式,这个呢就相当于我们叫这个阶段的模式,或者叫取整的模式。比如说我们将一个浮点数呢,转化成一个整数,那我们都是一个阶段的操作,对吧,那这呢就相当于是叫向零舍入的一个模式,这个不用多说,这个咱们这个,呃,已经有这个相应的开发经验了,咱们都知道这样的行为,下面呢提到一个叫na的一个使用。说呢,当一个操作产生溢出的时候呢,这个将会使用有符号的无穷大来表示啊,这个咱们也有一个相应的这个操作,一会儿咱可以看一下,然后如果呢,某个操作这个结果呢,没有明确的数学定义的话呢,那我们就会使用呢,叫na来表示这个运算的结果。啊,同时呢,把这个结果呢,做一个返回行,那针对这块呢,咱们稍微的在这块给大家说一个这样的例子。这呢,不知道大家平时开发中有没有做过类似这样的操作,好首先呢,这块来看一下,嗯,这其实说的是两个事儿,第一个呢,就是提到这个无穷大的一个问题,对吧,那无穷大的一个问题呢,怎么去体现呢?这个咱们可以这样。
03:10
首先呢,我这里边,比如我定义一个int型的一个变量,比如这个变量叫I,这个值是零啊,或者先别是零啊,咱们先来一个十。然后呢,让这个I呢,我们去除以一个零,这个时候呢,大家应该知道问题对吧。打印一下这个接这个呢,我们要想去执行,咱这用一个单元测试方法吧。这样那这个的话呢,是不是就说提到了咱们刚才提到的这个叫arithme exception这样一个异常对吧。哎,那确实出现了,行,那现在呢,我不是写的是零,我写成个0.0,那进而的话呢,这块咱们改成是一个double类型。这个W型这个变量名我就不变了,那当我们让十去除以一个0.0,这个数据呢,你看成是极小,小到极限就是零,那我们除一个特别小的数,按说结果呢,是不是就特别大了,那这时候咱们再跑一下看看这个结果。
04:03
嗯,看到了对吧,那么这个结果呢,Infinity它就是表示无穷大的意思,哎,它就表示无穷大的意思,那这呢,就是我们说的这叫哎无穷大。OK,然后无穷大,这是一种结果,就是有符号,这个使用有符号的这个无穷大来表示,那还有一种情况呢,叫n na,你像我们下边这个结果呢,是不是就出现了叫na,对吧?那么这个呢,我们通常翻译成了叫not a number,就是不确定的一个数值。那我们看一下什么情况下出现的,这呢,我定义一个double叫0.0,然后呢,除数呢也是0.0,那按咱们通常理解的道理来说,说被除数跟除数呢是相同的,那你这块除完之后,结果按说该是一,对吧,但是呢,由于你这个分母呢,哎,分子呢是零,咱说零除以任何数,按说结果都是零,但你现在又说是一,那再换一个道理来说,你要看分母的话呢,分母是0.0,那一个数除以0.0,按说这个数就该无穷大的,所以导致了我们这个结果,那到底该是多少呢?所以这里边我们说叫na,就是不是一个确定的数值。
05:09
这呢就相当于我们扣的是这种极特殊的这种情况,这个结果呢,大家的一个理解,好,这呢是咱们说的关于这个算术运算符的一些基本的情况啊,还没有引入咱们说具体的算术运算符呢,下面呢,咱们来看一下所有的这个算术运算符都有哪些。这里边儿呢,提到了加减乘除求余这个取法自增未运算符,还有比较运算符。那严格上来讲,咱们其实现在呢,不应该叫做算术指令了。能理解吧,什么叫算术指令,就是咱们所说的加减乘除啊,这个呃,正号负号啊,包括呢,像字符串那个连接呀,咱们称为呢叫算术运算符,像这种呢,是不是就叫未运算符啊,这叫比较运算符对吧?那还有这个像取法的那个操作,只不过呢,咱们看Java虚拟规范的时候呢,都统一的把这就成为了叫算术指令了。
06:02
因为确实呢,底层来看都是一些数值在运算嘛。对吧,哎,确实也是一些数值做运算,所以呢,就统称为呢,叫算术指令啊也也也不为过啊行,那这里边儿呢,我们细节去看的话呢,像加法这块ILFD都有。咱们像原来讲是不是还有一个A是吧,但是这时候你注意咱们说这个引用类型的话呢,就不能加减乘除了,所以这就没有A,只有这个ILFD这样的几个类型。加呢叫A,减呢叫subtract,所以这呢就是只取前几个字母,乘呢multiply,那就是ull,除呢,Divide啊div,然后这个求余,这个余呢是remainder这块我怕大家不熟这个单词,把它就写出来了,这表示余数的意思,所以你看到rem呢表示就是求余。那neg的话呢,你G是吧,取反的意思,取反的意思,这个自增I就是rement或者动词呢,叫increase对吧,就是自增的意思,那位移算符呢,我们涉及到叫是不是左移,这个是左移的意思,这是叫右移,这个呢叫无符号右移,这个呢是针对于这个long类型的,这个左移右移和无负号右移啊这块呢,就不涉及到我们说浮点类型的对吧,然后按位呢或运算哦,余运算and,异货运算X or。
07:20
具体的这些运算符具体的意思我就不用多给大家讲了吧,大家做Java开发开发呢,这都是属于基本的操作对吧,然后比较运算符呢,这块就涉及到了这样的几倍。哎,涉及到这样的几类,好,那下边的话呢,我们具体的来这个看一看这个相关的一些例子啊,哎,关于比较运算方等一下,咱们再稍微的强调一下,那关于咱们上面先提到的这些。咱们呢,先举一些例子啊,带着大家来看一看,那首先的话呢,咱们来看一下咱代码这块。嗯,这个呢,是我们的单一测试方法,这个你现在把它删也行,不删也可以啊,嗯,把咱们当前这个整个程序呢,咱们做一个重新编译。然后这块呢,我们打开一下这个。
08:02
解析好,我们这块刷新一下也行,先看一下这个MASTER2。MASTER2这块,那MASTER2这块呢,相对来说呢,比较简单一些,我这块就不在咱们这个Excel里边呢,给大家去画特别详细的图,咱们就画一个简图就可以,根据这样的几个最解码指令,首先的话呢,这里边我们flow的类型是个十,那咱们用这个BI push啊,SI push啊,这个已经不太靠谱了,那你是个flow的类型嘛,所以这时候呢,我们是用的LDC这个呢是十。嗯,从咱们这个常量池里边,把这个式呢,给大家取出来,那针对于咱们这个,我这样画一下,横着的呢,这叫局部变量表,纵着的这个呢,我们叫操作数占。在咱们这个MA2里边呢,首先这里边第一个索引零的位置呢,这是Z次,这不用多说了,所以一的位置现在呢,我们马呃现在还没有呢,是吧,马上现在就有它了,首先呢,是在咱们这个操作入站里边呢,加载进来一个叫10.0。嗯,放在这儿,然后呢叫F到杠一,就是flow的类型呢,我们存储在角标一的局部变量表当中,相当于把这个10.0是不是就放在这了。
09:09
那这时候我们这个数据就出账了,就没有了,再接着的话,F float的杠一把我们这个这个float的类型的,嗯,局部变量表当中是一的这个数据给它再取出来,相当于这个10.0又进来了。进来之后呢,叫f neg neg呢就是取它的一个负数的意思,那取负数这块相当于把这个数呢,是不是取个负数,先拿出来取个复数,复数完以后呢,再放进去,就这个意思。这个放进去以后呢,接着就F到杠二,把这个放在我们的这个位置,就是角标为二的这个位置,那就负10.0对吧,那这个负10.0其实在我们这儿呢,就是咱这个接这个变量呗,这个是我们这个I这个变量。没问题,再呃,注意这个Z次的话,其实咱也应该写外边,这就是你放当前对象那个地址值了,然后再往下的话呢,是这个操作已经放到这儿了,然后f load2把我们这个负10.0呢,再给他这个刚才呢。
10:04
到完以后呢,这个就没有了,然后再接下来呢,把这个F漏的杠二,把这个数据呢,再接着加载到我们操作入站当中,你现在是负10.0嘛。再拿过来,拿过来以后呢,把它再进行一个这个求加一个符号。啊,加一个负号,现在取它这个负数的这个值,那取完负数先拿出来,取完负数以后呢,那就变成正十了,然后把这个值的话呢,再F到到一这个位置,一就是它,然后再回过来,那就到这儿。嗯,这个覆盖一下,这个原来其实是十,现在我们覆盖一下还是十对吧,写到这儿,那这个值呢,也就没有了,那最后呢,这个有个return操作,整个呢就结束,这里边没有数据,这里边呢,就这样的三个数据。没问题吧?这呢是咱们说这个METHOD2这个操作行,这边有neg neg呢在咱们刚才讲解的这里边,那这不就是它吗?就是取法的那个操作啊行,那接下来我们再看一下这个METHOD3。
11:01
METHOD3METHOD3里边我们还是画这个简图,这个呢是我们说的局部变量表,这呢是咱们说的操作数站。首先我们在这个里边,还是这有一个this。这个Z4,然后这有个阶对吧,我写的是阶,其实呢,当我们调用这个方法的时候呢,你得传一个具体的数嘛。对吧,具体的一个数,那这个数传过来以后呢,它就有一个具体的值,然后接下来呢,我们再往下看,我呢在方法体里面,首先呢,这是一个100,那100呢,咱们知道是在BA的范围内,所以呢就是BI push,首先呢在这整一个100放到这个参数占里边,然后把这个值呢存储在I store这个角标为二的位置,这是角标零,角标一,角标二,放到我们这个局部变量表里边,把这一摆出来放这儿。那这个呢,就没有了。放在这以后,这个值呢,其实咱们给它赋给了这个变量叫I对吧。OK,然后再接下来呢,我们这个I漏的下线二,把这个100呢,再取出来放在这儿。
12:01
放在这儿以后,然后呢叫BI push10,我们再取一个这个十。放到我们这个操作站当中,然后呢叫ID,就是我们取这个你操作站最顶端的这两个数据,让他俩都出站,出站完以后呢,做一个加的操作,那这个操作完以后,这是不是就变成一百一了。对吧,一百一把这一百一呢,放在这儿之后呢,接下来S到下划线二,那把这个数据呢,再复制给我们这个位置,把它改成叫110。这个呢就结束了。这就是我们现在这个操作,这不就实现了我们这个I变量呢,做了一个加时的一个操作,对吧?哎,在这个位置上行没问题啊,然后呢,咱们这块我把它呢,注释一下,把这个打开。你看这个区别,这呢是我们让I呢跟这个操作数站当中这个常量时呢,做一个加的运算,而我们这呢叫自增对吧。那咱们再做一个编译。我这块呢,再来一个刷新,好大家看一下我们此时的这个操作。
13:00
这呢是咱们说的这个叫U变量表,这是操作站,一开始的时候呢,这也是100,这呢有个Z4这一个阶是吧,然后这100的话呢,然后放到这儿,接下来呢,I到二,把它直接存储在我们这个角标零,角标一,角标二放到这儿,100放到这了,然后接下来呢叫I,嗯,INC,这个就是crement,就是增加给我们这个角标二的这个值,给他这个值呢,BY通过十做一个增加,相当于呢,就是加了一个十的操作,那就变成一百一了。就变成100亿了,然后直接呢做个return,所以这这块大家就看到它就相当于直接针对于我们这块呢,做了一个增,不像原来那ii的啊,取咱们这个操作站里边两个数,然后呢做一个加的运算是吧,这个呢直接自增,哎,就是这样个区别,所以这两个呢不一样。咱们在讲Java语言的时候提到过,如果这个I呢,是一个比如说bad类型,跟那个十作家是不是就变成in的类型了,而我们这个的话呢,如果是个bad类型,这样操作呢,编译就不报错,它属于自增,对吧,OK。
14:03
然后呢,我们再看一下这个METHOD4。看这。其实呢都类似对吧,大家呢,看几个之后呢,应该就都差不多了哈,这呢我们就多给大家呢举几个例子,这呢还是局部变量表,这个呢是操作数站,首先这里边呢有个Z次,角标零,角标一,角标二,角标三,我这就先多写几个啊,不一定能到三这块第一个是Z次,然后接下来我们在这里边,首先B是80,把80呢放在这。然后S到一这个80呢,就存到这儿了,这个其实对应的就是我们变量A。然后呢,在B是七,这个七呢S到二,然后这个是七放在这,这其实就是B,再接着呢,B是十,然后这个十呢,在S到三,十放在这,这其实就是C。行,然后呃,这个当然我们是拿出来一个这个原有这个数据就没有了啊,然后在下边呢,涉及到了后边在这块了,这块的话呢,我们取出I漏一,I漏二,把这个80拿过来,把这个七拿过来,Ii的操作它俩都出站,然后呢,一加87抹掉之后,87这个还是咱们这个站里边啊,我就往上写了87,这个87完了以后,这个叫ILO的三,这个还在我们站里边,ILO3把这个十呢也拿过来。
15:20
然后这呢进行一个乘法,这一乘870,这个干掉,干掉出站之后呢,乘完八百七再放到我们这个操作站当中,然后整个把这个结果呢,做一个return,返回的是一个int类型,这个咱们后边讲方法的返回时候会提到这个I。行,这就是这样一个场景。没问题,好,然后再往下这个呢,METHOD5是不,我们就涉及到一个取法的一个操作了,对吧。好看一下这个这个呢,稍微里边有一点运算量,大家看一下。那首先也是,这呢是我们说的局部变量表,这呢是咱们的操作数占我画的稍微长一点。110123。哎,我就先往后写几个,不一定能到这儿,首先第一个位置呢,也是这次对吧,这呢放你具体的对象的地址值,然后呢,我们这有一个I有个接,嗯,这是I,这是阶放这你调列方法的时候呢,一定会负个值,那这个值呢,你就给人家写到这。
16:15
这个意思行,那接着来我们看这里边首先的话呢,我们一进来这个方法体里边做操作的话呢,先把llo的1ILO2给加载过来,这个咱们嗯,举个例子吧,比如我们这块呢,写的是个一,这块写的是个二,就是负的值是一二啊这个大家注意,那这个就是一个,嗯,或者这个写成十,这行20吧,跟咱们这个角不要区分开,这是十,这是20。行,嗯,首先呢,把这个I漏的一把这个十呢给他拿过来,在IO的二把20呢拿过来。Ii的这俩呢都出去,出去之后呢,一座和一座河呢是30,把这个30呢放回来。就到这儿了,然后I cost_一,注意这个呢是一个常量一。
17:01
长量一,我们这块呢,放在这儿不是角标啊,接着呢做一个I sub减法,那就是我们这里边这个减法操作这两个都出去,30减一,30减一变成29,嗯,到这了就放到这。然后接下来呢,叫I,其实这块相当于我们把这个结果是不是就计算完了,这个结果是不是就29啊目前对吧,如果你负值是十二十的话,这就29。在下面的话呢,叫ILO的2I的二,这20好把20呢翻过来,哎,这个咱们就。诶,这个不能,这个不能划掉。注意我画错了啊,不能划掉,因为它没有往我们一个变量上去存,所以这个29呢还在这啊,打个对勾吧。然后呢,I漏二,把我们这个二位上这20呢拿过来,20过来了,然后在ICON1放个一。嗯,这现在目前这里边有这仨,嗯,然后有个s sub做一个减法,减法呢就是20减一,20减一,这个干掉,这个干掉变成19。
18:00
19这就对应的我们这个操作对吧?行,19拿到了到这儿了,然后再下边呢,Icon me,注意me的话咱们说过就是负一的意思。嗯,然后呢叫X2,这是一个异或操作。是吧,是个疑惑操作咱们,嗯,咱们这块呢,是一个整个的一个取反操作。这个取反操作能理解吧,这个取反操作,这怎么现在我们用的一个X or叫抑或呢?能理解这个事儿吗?大家想想能理解吗?就是正常来讲,你不应该是取反,什么叫取反,比如说我现在是0101,那我现在取反之后呢,是不是应该变成叫1010呢,怎么就能从0101变成1010呢?你看这里它用了一个非常巧妙的操作,我呢从这个常量里边取一个叫负一,让19跟这个负一啊做一个异或的操作,负一一会咱们这个,因为我现在不能擦,咱们看下计算器负一呢,其实这个从二进制上来讲就是全是一。
19:00
全是一的,这个结果呢,其实就是负一,那比如说我们这个是0101这个数,那我让他跟这个四个一做一个异或运算的话。大家想做一或运算,就是说你这两个要一样的话呢,结果就是零,这俩俩不一样呢,结果就是一,你看这样一做异或是不是就是一,一就变成零了,零一就变成一了,这是零,这是一,哎这块呢,其实不就相当于达到一个取反的效果吗?所以这个取环怎么做的呢?就是我们让你得到这个数呢,跟这个负一呢,求一个一或就可以了,比较巧妙。行,这就得到这个结果了,那这个运算完以后,这个出去,这个出去做个疑惑,哎,得到一个值,这个咱们一下口算不出来,那这个值跟咱们还存在的这个29,刚才不是说29还存在吗?它俩呢,嗯,这有一个Ian的就是与的运算,它俩呢,再都出去与运算,算一个数,把这个数呢,是不是再回来放进来啊。那那整个这个是不是就运算结束了。能行吧,哎,整个就运算结束了,行,那这里边呢,咱们就给大家举了一些这个例子,那刚才这里边儿涉及到的这个运算符,咱们在这块呢,哎,都涉及到了。
20:08
啊,其实不是特别困难,主要呢,大家还是去熟悉,咱们在上一节当中讲到的这个叫加载与存储,你得清楚,就是具体的哪些指令呢,是往站里边放的,哪些指令呢,是往咱们这个。叫什么局变量表里放的啊,其实局部变量表里边放,就是我们说的那个叫store是吧,Store呢是往局部变量表里边放的啊行,那这个呢,是我们说的这样的几个例子。哎,先把这个我们停一下。
我来说两句