温故而知新之基础数据类型(基于jdk8)

basicDataType基础数据类型(基于jdk8)

  • 基本信息
name内存位数数据范围包装类说明
byte8-27~27-1Byte
short16-215~215-1Short
int32-231~231-1Integer
long64-263~263Long
float32-2^128 ~ +2^128Float符号位1位,指数位8位,位数为23位
double64-2^1024 ~ +2^1024Double符号位1位,指数位11位,位数为52位
char16CharacterUnicode字符集
booleanBoolean
  • 包装坑

    • java可以自动的将基本类型转换为包装类型,称为装箱,将包装类型转换为基本类型称为拆箱
    • byte、short、int、long的缓存
      • 以上包装类型都包含-128~127之间的值,所以在自动装箱的过程中会使用缓存,所以创建的对象一样,超过这个范围就不会使用缓存

      •   Integer a = 1;
          Integer b = 1;
          System.out.println(a==b);//true
        
      • Integer.valueOf(1)等价于Integer a= 1,也会使用缓存,所以这两个方法创建的对象是相同的。

      •   Integer a = 1;
          Integer b = Integer.valueOf(1);
          System.out.println(a==b);//true
        
      • 所以在实际项目中使用valueOf()或者装箱来声明对象,因为这样创建时读取缓存中的对象,更加快速,而且也节省了空间;

      •   Integer a = 1;
          Integer b = Integer.valueOf(1);
          Integer c = Integer.valueOf(2);
          b = 2;
          System.out.println(b==c);
        
  • float、double在计算机中的表示

    • 小数在计算机中的表示

      • 小数位2取整数位剩余的小数位2再取整数位,循环下去,直到小数位为0

      — 0.1 计算

      > 0.1*2 = 0.2  ---> 0
      >
      > 0.2*2 = 0.4  ---> 0
      >
      > 0.4*2 = 0.8  ---> 0
      >
      > 0.8*2 = 1.6  ---> 1
      >
      > 0.6*2 = 1.2  ---> 1
      >
      > 0.2*2 = 0.4  ---> 0
      >
      >一直循环下去
      - 所以值为000110011.....
      - 但是计算机存储数字的位数是有限的,所存储时会截取至一定位数,这样就造成了计算机对0.1的表达不正确的问题。
      - 由于0.1的表达不正确,所以0.1与其他数字的运算都有可能造成不准确的情况。
      
      • 5.1表示
        • 整数位5二进制位101,小数位0.1表示为000110011…
        • 所以5.1二进制表示就是101.00011001100,科学计数法表示就是1.01000100110011*2^2
        • float表示
          • 符号位0表示正数,1表示负数,所以为0
          • float指数位为8位,但是区分正负,正负各一半。所以用1000 0000表示正数1,以此类推。5.1的指数为2.所以表示为1000 0001
          • float数位为23位,取0.1的二进制的23位,1010 0010 0110 0110 0110 011
            • 但是科学计数法的第一位都是1,所以不用记,所以又省出来一位,改为0100 0100 1100 1100 1100 110(最后一位0就是补上来的)
          • 到这里。就可以确定5.1在float中是如何存储的了
            0 1000 0001 0100 0100 1100 1100 1100 110
          • 这里的5.1就不是精确存储
        • double表示与float原理相同,只是存储的更加精确了
  • 金额能用double或者float表示吗?

    • 首先说答案,不能。

    • 因为double和float位数有限,无法表示很大的数字,比如Long.MAX_VALUE.不能表示的部分会舍弃,所以即使+1也在表示的时候设计,所以数字不会有变化。
      — 举一个很现实的例子,假如一个人有2^60元钱,放到银行里每天产生利息1000元,用代码实现

    •    double k =Math.pow(2, 60);
         double k1 =k;
         for(int i=0;i<100000000;i++){
             d1 += 1000;
         }
         System.out.println(k1==k);//true
      
    • 结果是相等的,说明并没有吧这1000加到里面,也就是说不管多长时间,利息都加不上去,钱在银行不能生出利息

    • float精度更小,更加不能用于这个场景。

    • 所以在生产中金额使用bigdecimal

      • bigdecimal原理
        • bigdecimal采用十进制
        •   BigDecimal bd = new BigDecimal("100.001");
            //指数位
            System.out.println(bd.scale());//3
            //有效数字
            System.out.println(bd.unscaledValue()); //100001
          
        • 100.001=100001*0.1^3
      • 由于十进制能准确的表达每一个数字,所以能够正确的加减
      • 这里要注意的是申明一个bigdecimal对象是最好是使用string类型构造器,而不是直接的使用数字,使用数字会导致精度丢失,
        •   BigDecimal a = new BigDecimal(1.01);
            BigDecimal b = new BigDecimal(1.02);
            BigDecimal c = new BigDecimal("1.01");
            BigDecimal d = new BigDecimal("1.02");
            System.out.println(a.add(b));
            System.out.println(c.add(d));
            
            输出:
            2.0300000000000000266453525910037569701671600341796875
            2.03
          
    • 其他说明
      double和float也不是一无是处,它主要是科学计算和工程计算,它的计算速度比较快,对于一些要求不是特别精确的计算场景十分有用

  • 参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值