天天看點

JAVA——Double 和Float的除法問題摘要出現的問題解決方案

摘要

Java中的浮點數類型float和double不能夠進行運算,因為大多數情況下是正常的,但是偶爾會出現如上所示的問題。這個問題其實不是JAVA的bug,因為計算機本身是二進制的,而浮點數實際上隻是個近似值,是以從二進制轉化為十進制浮點數時,精度容易丢失,導緻精度下降。

出現的問題

JAVA——Double 和Float的除法問題摘要出現的問題解決方案
package 計算機程式算法分類.數學問題;

import java.math.BigDecimal;

/**
 * @Classname average_double
 * @Description TODO
 * @Date 2021/5/3 21:17
 * @Created by xjl
 */
public class average_double {
    public static void main(String[] args) {
        float[] arr = new float[]{45.0f, 54.0f, 98.0f};

        System.out.println("**********************************************");
        System.out.println("出現的錯誤的方式"+test1(arr));
        System.out.println("**********************************************");

        System.out.println("完美解決的方法"+test3(arr));
        System.out.println("**********************************************");

        System.out.println("使用的BigDecimal函數的問題"+test2(arr));
        System.out.println("**********************************************");

    }

    public static float test1(float[] arr) {
        float sum = 0f;
        for (float f : arr) {
            sum += f;
        }
        float res = sum / arr.length;
        return res;
    }

    public static float test2(float[] arr) {
        float sum = 0f;
        for (float f : arr) {
            sum += f;
        }
        String res = new BigDecimal(sum).divide(new BigDecimal(arr.length)).toString();
        return Float.valueOf(res);
    }

    /**
     * @description TODO  原來JAVA中如果用BigDecimal做除法的時候一定要在divide方法中傳遞第二個參數,定義精确到小數點後幾位,否則在不整除的情況下,結果是無限循環小數時,就會抛出以上異常
     * @param: arr
     * @date: 2021/5/7 9:37
     * @return: float
     * @author: xjl
     */
    public static BigDecimal test3(float[] arr) {
        float sum = 0f;
        for (float f : arr) {
            sum += f;
        }
        BigDecimal res = new BigDecimal(sum).divide(new BigDecimal(arr.length), 20, BigDecimal.ROUND_HALF_UP);
        return res;
    }
}
           

解決方案

使用的java中可以很好的解決的精度問題。這個思路就是将的float類型轉為的string 類型。然後在去的相關的加減等操作。

BigDecimal res = new BigDecimal(sum).divide(new BigDecimal(arr.length), 20, BigDecimal.ROUND_HALF_UP);