前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >1+1=2是如何运算的

1+1=2是如何运算的

作者头像
shysh95
发布2021-02-25 10:46:51
9840
发布2021-02-25 10:46:51
举报
文章被收录于专栏:shysh95

上一节讲述了加载和存储指令,但是如果只知道存取,JVM便没有了灵魂。计算机,计算两个字才是关键,那么作为JVM也需要去进行计算,最简单的计算莫过于加减乘除,下面看一下加减乘除的具体指令有哪些,文章的结尾我们也会给出1+1=2的运算过程。

运算指令

  • 加法指令:iadd, ladd, fadd, dadd
  • 减法指令:isub,lsub,fsub,dsub
  • 乘法指令:imul,lmul,fmul,dmul
  • 除法指令:idiv,ldiv,fdiv,ddiv
  • 求余指令:irem,lrem,frem,drem
  • 取反指令:ineg,lneg,fneg,dneg
  • 位移指令:ishl,ishr,iushr,lshl,lshr,lushr
  • 按位或指令:ior,lor
  • 按位与指令:iand,land
  • 按位异或指令:ixor,lxor
  • 局部变量自增指令:iinc
  • 比较指令:dcmpg,dcmpl,fcmpg,fcmpg,lcmpg

当进行除法和求余计算时,如果除数为0,那么则会抛出java.lang.ArithmeticException异常,其余任何场景都不应该抛出运行时异常。

JVM在实现运算指令处理的时候必须遵循IEEE 754规范。

  • JVM要求在进行浮点数运算时,所有的运算结果都必须舍入到适当的精度,非精确的结果必须舍入为可被表示的最接近的精确值。如果有两个同样接近的精确值,那么最低有效位为0的优先(最接近数舍入模式)。
  • 浮点数转化为整数时,使用向零舍入模式(直接将小数位抛弃)
  • 在对long类型数进行比较时,虚拟机使用带符号的比较方式,对浮点数进行比较时,使用无信号比较方式

类型转换指令

类型转换指令可以将两种不同的数值类型进行转换,JVM直接支持以下类型的宽化类型转化:

  • int到double、long、float
  • long到double、float
  • float到double

但是窄化类型转换则需要类型转换指令的支持,类型转换指令主要有以下几种:

  • i2b:int -> byte
  • i2c:int -> char
  • i2s:int -> short
  • l2i:long -> int
  • f2i:float -> int
  • f2l:float -> long
  • d2i:double -> int
  • d2l:double -> long
  • d2f:double -> float

int或者long类型的窄化只需要将最高的几位丢弃,保留最低的N位(N为转换后的数据类型长度)即可,因此在窄化后会出现正负号的差异。

float和double窄化成整数类型,需要采取向零舍入(结果朝0的方向进行舍入)的规则,如果是10.9,转换成int以后就是10,如果浮点数转换后超过了int或者long的范围,那么会根据向零舍入后的数据的符号返回其最大或最小的正数,这里特别强调是正数。

1+1=2

代码语言:javascript
复制
public class ClassTest {

    public int add(int a, int b) {
        return a + b;
    }
}

我们看一反编译后的Class文件,如下图:

着重看红框中的部分,红框中的含义就是将局部变量表中的第二个(a)和第三个元素(b)依次压入操作数栈,然后使用iadd弹出操作数栈顶两个元素进行加法运算,将结果再压入操作数栈顶,最后一个ireturn实际是将栈顶的元素进行返回(也就是a+b的结果)。

本期的运算和类型转换指令就介绍到这,我们下期再见!!!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员修炼笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档