Solution to the problem of precision loss caused by operation of double and float types

In the process of operation, we may inadvertently lose precision. How can we solve this problem? Don't panic, this article is to introduce the problem of precision loss.

Let's look at the following code:

        double price1 = 10.01d;
        double price2 = 10.0d;
        double v = price1 - price2;
        Log.e("double====", "init: "+v );

It is reasonable to say that the result of subtracting two numbers is 0.01, but the fact is not as we think. Let's take a look at the print results below.

12-29 09:09:04.001 9674-9674/com.wekair.app E/double====: init: 0.009999999999999787

It is found that the printed result is a series of numbers of 0.009999999999979787, resulting in the problem of accuracy loss. Let's look at the solution:

1. Wrong solution:

        double price1 = 10.01d;
        double price2 = 10.0d;
        BigDecimal bigDecimal = new BigDecimal(price1);
        BigDecimal bigDecimal1 = new BigDecimal(price2);
        Log.e("double====", "init: "+bigDecimal.subtract(bigDecimal1) );

Let's take a look at the code above, which uses the BigDecimal object to pass in two prices: the problem should be solved reasonably, and the result is not as we thought, let's take a look at the real printing result:

12-29 09:21:34.084 11165-11165/com.wekair.app E/double====: init: 0.0099999999999997868371792719699442386627197265625

2. Correct solution: we change the price of the double type passed in in the wrong method to the String type, and the modified code is as follows:

        double price1 = 10.01d;
        double price2 = 10.0d;
        BigDecimal bigDecimal = new BigDecimal(Double.toString(price1));
        BigDecimal bigDecimal1 = new BigDecimal(Double.toString(price2));
        Log.e("double====", "init: "+bigDecimal.subtract(bigDecimal1) );

Let's take a look at the print results, as follows:

12-29 09:27:11.361 11745-11745/com.wekair.app E/double====: init: 0.01

For your better use, I encapsulate a tool class for you to use to achieve the function of addition, subtraction, multiplication and division.

package com.wekair.app.utils;

import java.math.BigDecimal;

/**
 * File Name:BigDecimalUtil
 * Author:jinghui liu
 * Created Time:2017/12/28 14:49
 */

public class BigDecimalUtil {

    /**
     * add
     *
     * @param number1
     * @param number2
     * @return
     */
    public static double add(double number1, double number2) {
        BigDecimal bigDecimal = new BigDecimal(Double.toString(number1));
        BigDecimal bigDecimal1 = new BigDecimal(Double.toString(number2));
        return bigDecimal.add(bigDecimal1).doubleValue();
    }

    /**
     * subtract
     *
     * @param number1
     * @param number2
     * @return
     */
    public static double sub(double number1, double number2) {
        BigDecimal bigDecimal = new BigDecimal(Double.toString(number1));
        BigDecimal bigDecimal1 = new BigDecimal(Double.toString(number2));
        return bigDecimal.subtract(bigDecimal1).doubleValue();
    }

    /**
     * multiply
     * @param number1
     * @param number2
     * @return
     */
    public static double mul(double number1, double number2) {
        BigDecimal bigDecimal = new BigDecimal(Double.toString(number1));
        BigDecimal bigDecimal1 = new BigDecimal(Double.toString(number2));
        return bigDecimal.multiply(bigDecimal1).doubleValue();
    }

    /**
     * div
     *
     * @param number1
     * @param number2
     * @param scale
     * @return
     */
    public static double div(double number1, double number2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("Parameter error");
        }
        BigDecimal p1 = new BigDecimal(Double.toString(number1));
        BigDecimal p2 = new BigDecimal(Double.toString(number2));
        return p1.divide(p2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
}

Tags: Java

Posted on Mon, 04 May 2020 12:37:23 -0700 by Batosi