• Java 浮点数+-丢失精度的问题:BigDecimal


    public static void main(String[] args) {
    		Double aa = 1.06;
    		Double bb = 2.03;
    		
    		Double cc = bb-aa;
    		Double dd= new BigDecimal(cc).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    		System.out.println(cc);//0.9699999999999998
    		System.out.println(dd);//0.97
    		System.out.println(new BigDecimal(cc));//0.96999999999999975131004248396493494510650634765625
    		
    		BigDecimal aaa = new BigDecimal(11.01);
    		BigDecimal bbb = new BigDecimal("11.02");
    		BigDecimal ccc = BigDecimal.valueOf(11.03);
    		
    		BigDecimal zero = BigDecimal.ZERO;
    		BigDecimal one = BigDecimal.ONE;
    		BigDecimal ten = BigDecimal.TEN;
    		
    		System.out.println("new BigDecimal(11.01):"+aaa);
    		System.out.println("new BigDecimal("11.02"):"+bbb);
    		System.out.println("BigDecimal.valueOf(11.03):"+ccc);
    		
    		System.out.println("BigDecimal.ZERO:"+zero);
    		System.out.println("BigDecimal.ONE:"+one);
    		System.out.println("BigDecimal.TEN:"+ten);
    		
    		bbb.add(ccc);
    		System.out.println("bbb.add(ccc);bbb=:"+bbb);
    		
    		bbb = bbb.add(ccc);
    		System.out.println("bbb=bbb.add(ccc);bbb=:"+bbb);
    
            
                    /**
    	    * 	0.9699999999999998
    			0.97
    			0.96999999999999975131004248396493494510650634765625
    			new BigDecimal(11.01):11.0099999999999997868371792719699442386627197265625
    			new BigDecimal("11.02"):11.02
    			BigDecimal.valueOf(11.03):11.03
    			BigDecimal.ZERO:0
    			BigDecimal.ONE:1
    			BigDecimal.TEN:10
    			bbb.add(ccc);bbb=:11.02
    			bbb=bbb.add(ccc);bbb=:22.05
    	    */
    
    	}
    

      

    1、解决浮点数加减丢失精度的问题:BigDecimal

    double 和 float 都是浮点数,计算机是二进制的浮点数,直接计算会丢失相应的精度,

    如上面的Double cc = bb-aa;System.out.println(cc);//0.9699999999999998

    很明显就不准确,此时,可以通过BigDecimal来解决这个问题  java.math.BigDecimal

    (1)把计算结果转为BigDecimal类型的

    Double dd= new BigDecimal(cc).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    

    setScale(2, BigDecimal.ROUND_HALF_UP) 保留2位小数,
    BigDecimal.ROUND_HALF_UP(4) 表示四舍五入
    BigDecimal.ROUND_HALF_DOWN(5) 表示五舍六入

    (2)BigDecimal 自带的方法来加减

    public BigDecimal add(BigDecimal value);//加法
    public BigDecimal subtract(BigDecimal value);//减法 
    public BigDecimal multiply(BigDecimal value);//乘法
    public BigDecimal divide(BigDecimal value);//除法
    
    
    BigDecimal aaa = new BigDecimal(Double.toString(aa));
    BigDecimal bbb = new BigDecimal(Double.toString(bb));
    BigDecimal ccc = bbb.subtract(aaa);
    Double cc = ccc.doubleValue();
    

     

     

    2、创建BigDecimal对象

    BigDecimal aaa = new BigDecimal(11.01);精度会缺失,数值不准确
    BigDecimal bbb = new BigDecimal("11.02");准确
    BigDecimal ccc = BigDecimal.valueOf(11.03);准确

    最好使用字符串来创建,不要直接用double值创建

    3、BigDecimal.ZERO 提供了默认值可以直接用

    如上代码

    BigDecimal zero = BigDecimal.ZERO;

    4、BigDecimal 提供的加减乘除

    public BigDecimal add(BigDecimal value);//加法
    public BigDecimal subtract(BigDecimal value);//减法
    public BigDecimal multiply(BigDecimal value);//乘法
    public BigDecimal divide(BigDecimal value);//除法

    BigDecimal的运算都没有对原值进行操作,而是返回一个新的BigDecimal对象
    因此加减乘除、都需要自己再接收这个值

    bbb.add(ccc);bbb=:11.02
    bbb=bbb.add(ccc);bbb=:22.05
    

      

    public BigDecimal add(BigDecimal value);

    public static double add(double value1,double value2){
      BigDecimal b1 = new BigDecimal(Double.toString(value1));
      BigDecimal b2 = new BigDecimal(Double.toString(value2));
      return b1.add(b2).doubleValue();
    }
    

      

    5、compareTo

    BigDecimal的比较用的是BigDecimal的compareTo方法,将此 BigDecimal 与指定的 BigDecimal 比较。
    根据此方法,值相等但具有不同标度的两个BigDecimal对象(如,2.0 和 2.00)被认为是相等的。
    当此 BigDecimal 在数字上小于、等于或大于被比较对象时,返回 -1、0 或 1。

    BigDecimal one = BigDecimal.valueOf(1);
    BigDecimal two = BigDecimal.valueOf(2);
    BigDecimal three = one.add(two);
    int i1 = one.compareTo(two);//-1
    int i2 = two.compareTo(two);//0
    int i3 = three.compareTo(two);//1
    

      

    参考:https://blog.csdn.net/cen_s/article/details/76472834

    -------------------------------------------------------------------------------------------------------------------------------------------------------------- 白云苍狗时光飞,嘻嘻哈哈一生追。哈!
  • 相关阅读:
    Installation request for topthink/think-captcha ^3.0 -> satisfiable by topthink/think-captcha[v3.0.0].
    /etc/sudoers配置错误导致的nova-api等异常
    修改ssh默认端口导致的虚拟机resize失败
    ansible自动化测试云平台多个网络角色间带宽(shell模块调用iperf)
    nova的服务心跳机制和服务状态监控机制的实现
    时间不同步导致的nova,cinder服务一会up一会down的来回跳跃
    利用ansible部署keeplived和haproxy集群
    利用ansible检测网络连通性(多个网段多IP)
    通过ansible安装etcd集群
    部署k8s statefulset
  • 原文地址:https://www.cnblogs.com/sangong/p/9440184.html
Copyright © 2020-2023  润新知