美文网首页
【JAVA基础】精度问题

【JAVA基础】精度问题

作者: 嘻洋洋 | 来源:发表于2019-06-10 09:48 被阅读0次

    1. 问题由来

    浮点型变量在进行计算的时候会出现丢失精度的问题,如:

     double b1= 0.05;
    double b2 = 0.01;
    double b3 =b1+b2;
    String s = String.valueOf(b3);
    System.out.println(s);
    System.out.println(b3);
    System.out.println(1.0 - 0.42);
    System.out.println(4.015 * 100);
    System.out.println(123.3 / 100);
    
    输出:
    0.060000000000000005
    0.060000000000000005
    0.5800000000000001
    401.49999999999994
    1.2329999999999999
    
    

    Java中进行浮点数运算的时候,会出现丢失精度的问题。那么我们如果在进行商品价格计算的时候,就会出现问题。很有可能造成我们手中有0.06元,却无法购买一个0.05元和一个0.01元的商品。
    Java中float的精度为6-7位有效数字。double的精度为15-16位。

    2. 使用BigDecimal来解决

    划重点:float和double只能用来做科学计算和工程计算。商业运算中我们要使用BigDecimal!
    (1)四种构造器
    BigDecimal(int) 创建一个具有参数所指定整数值的对象。
    BigDecimal(double) 创建一个具有参数所指定双精度值的对象。
    BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
    BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。
    目前只有String构造器才能保证精度不丢失,其它构造器丢失精度BigDecimal显的更为过分,如:

    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
    

    (2)加减乘除运算
    BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象:
    加法 bigDecimal1.add(bigDecimal2)
    减法 bigDecimal1.subtract(bigDecimal2)
    乘法 bigDecimal1.multiply(bigDecimal2)
    除法 bigDecimal1.divide(bigDecimal2)
    一般开发过程中,我们数据库中存储的数据都是float和double类型的。在进行拿来拿去运算的时候还需要不断的转化:

    public class BigDecimalUtil {
    
        private BigDecimalUtil() {
    
        }
    
        public static BigDecimal add(double v1, double v2) {// v1 + v2
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            return b1.add(b2);
        }
    
        public static BigDecimal sub(double v1, double v2) {
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            return b1.subtract(b2);
        }
    
        public static BigDecimal mul(double v1, double v2) {
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            return b1.multiply(b2);
        }
    
        public static BigDecimal div(double v1, double v2) {
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            // 2 = 保留小数点后两位   ROUND_HALF_UP = 四舍五入
            return b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP);// 应对除不尽的情况
        }
    }
    

    相关文章

      网友评论

          本文标题:【JAVA基础】精度问题

          本文链接:https://www.haomeiwen.com/subject/opprxctx.html