zoukankan      html  css  js  c++  java
  • java笔记5-运算符

    运算符涉及到一些运算(这句是废话) ,需要关注精度、溢出、运算优先级、类型自动提升、强制转型等问题,会在下面的内容中逐一讲解;当然了解计算在内存中的本质才是学好的关键。

    分类:

      按照操作数的数目进行分类  单目运算符 a++  双目运算符a+b 三目运算符(a>b)?x:y  这么分类好像没有任何意义

      按照功能进行分类:

        算数运算符

          +  -  *  /  %  ++  --

          这里整数除0会抛异常,小数除0会得到Infinity

        赋值运算符

          =  +=  -=  *=  /=  %=

          单独的算数计算相对比较简单,因此把算数运算符和赋值运算符一起讲解,需要搞清楚两种运算符之间的区别

        关系运算符(比较)

          >  >=  <  <=  !=  ==  

          关系运算符比较后会返回boolean类型true false 

        逻辑运算

          &(逻辑与)  |(逻辑或)  ^(逻辑异或)  !(逻辑非)  &&(短路与)  ||(短路或)

          逻辑运算符一般用来对多个关系运算符做判断,前后连接的是boolean结果,没有计算机基础的话可能对这几个符号比较陌生,这里解释下

          &:前后都是true才返回true     |:前后有一个true就返回true    ^:前后结果不一致返回true  !:单目运算符 将boolean的值取反

          &&:当第一个条件是false时,后面的就不需要看了,如果左边的是false的时候可以提高性能     &&:当第一个条件是true时,后面的就不需要看了       

        位bit运算

          &(按位与)  |(按位或)  ^(按位异或)  ~(按位取反)  <<(按位左位移)  >>(按位右位移)  >>>(按位右位移无符号)

          讲位运算之前,需要先科普下计算机的原码、反码、补码。原码展示的是一个数的二进制数 int类型的2 就是 00000000 00000000 00000000 00000010 至于反码和补码也都是用二进制数表示,只是和原码不同的表示方式而已,在java语言中,就是以补码的形式存在的。所以我们先要搞清楚原码和补码之间的相互转换

          原码---->反码--->补码

            正数:原码、反码、补码都是一样的(-0,-128这些特殊情况后续讲解)

            负数:

              原码--->反码   符号位不变,剩余位按位取反

              反码--->补码  末位+1

              原码--->补码  符号位不变,剩余位按位取反,末位+1

          补码---->反码--->原码

            正数:原码、反码、补码都是一样的

            负数:

              补码--->反码 符号位不变,剩余位按位取反

              反码--->原码 末位+1

              补码--->原码 符号位不变,剩余位按位取反,末位+1

    System.out.println(~-4);  //3
    System.out.println(3&5);  //1
    System.out.println(-2<<1); //2147483644

          概念讲解完了,来分析下上面几行代码的实际步骤

          -4的按位取反:

            -4的原码是 10000000 00000000 00000000 00000100

            -4的反码是 11111111     11111111      11111111      11111011

            -4的补码是 11111111 11111111 11111111 11111100               ---这就是-4这个数在java中的实际展示

            -4的按位取反(取反以后还是补码的形式) 00000000 00000000 00000000 00000011

            -4按位取反后的原码  00000000 00000000 00000000 00000011         ---所以-4按位取反以后得到的结果是3

          3&5:       

            3的原码是 00000000 00000000 00000000 00000011

            3的补码是 00000000 00000000 00000000 00000011

            5的补码是 00000000 00000000 00000000 00000101  

            按位与1相当与true 0相当与false

            按位与的结果(补码) 00000000 00000000 00000000 00000001

            正数的补码还是其本身 所以3&5结果是1

          -10>>>1 

            -8的原码是 10000000 00000000 00000000 00001000

            -8的反码是 11111111 11111111 11111111 11110111

            -8的补码是 11111111 11111111 11111111 11111000

            无符号右移一位后(补码)  01111111 11111111 11111111 11111100    因为正数的补码是其本身,转化成原码得到十进制 2147483644

            

     

    精度

      整型的计算是精确的,浮点型的是不精确的,尽量不要使用浮点型去计算,这里有一个没解决的问题为什么x是0.1y是0.0999.....

    int a = 5;
    int b = 5/2;   //b=2
    double x = 1.0/10;      //0.1
    double y = 1-9.0/10;   //0.09999999999999998

    溢出

      整数由于存在范围限制,如果计算结果超出了范围,就会产生溢出,而溢出不会出错,却会得到一个奇怪的结果

      整数运算在除数为0时会报错,而浮点数运算在除数为0时,不会报错,但会返回几个特殊值

         

    int a =2147483647;
    a=a+1;     //-2147483648  
    double d1 = 0.0 / 0; // NaN
    double d2 = 1.0 / 0; // Infinity
    double d3 = -1.0 / 0; // -Infinity

    类型自动提升

      类型自动提升考虑的是不同基本类型之间的计算,提升的方法,可以参考java核心卷I:

      如果两个操作数其中有一个是double类型,另一个操作就会转换为double类型。

      否则,如果其中一个操作数是float类型,另一个将会转换为float类型。

      否则,如果其中一个操作数是long类型,另一个会转换为long类型。

      否则,两个操作数都转换为int类型。

    一些容易出错的地方

    byte x = 1;
    x=x+1 //报错
    x=(byte)(x+1);  //x是变量空间里的byte类型  1是常量区里的int类型1 相加的时候会类型自动提升到int,再次赋值给byte类型的时候需要强制类型转换
    x+=1 //这里不会报错

      同样是byte类型 x=x+1会报错,报错的原因在代码在代码注释中已经解释过了,x+=1为什么不会报错,这里有两种解释,

        一种在笔记3中提到过,也是赋值运算符的特性,如果等号右边是常量则 会自动把int类型的1变成byte类型的1

        另一种解释:复合赋值 E1 op= E2等价于简单赋值E1 = (T)((E1)op(E2))其中T是E1的数据类型,op为操作符 我个人倾向第二种解释更好理解些,当然同时引申出来的问题就是复合赋值会有精度的损失。

    关于赋值运算的运算解析 博客https://blog.csdn.net/honeygirls/article/details/81321512说的很详细,这里引用下

     

      

  • 相关阅读:
    java日常问题和技巧1(BigDecimal与int相互转换、判断某元素是否在数组中、求两个List并集、int[]转Integer[])
    窗口小部件基础编写V1.0----没有Service
    使用MyBatis遇到的问题及解决方法(一)(持续更新)
    java工具类集合(一)
    idea部分操作(一)----持续更新
    单向链表(篇九)
    结构体(篇八)
    指针与字符串(篇七)
    数组字符串(篇六)
    循环与函数(篇五)
  • 原文地址:https://www.cnblogs.com/ysmdbk/p/10905780.html
Copyright © 2011-2022 走看看