摘要
Java中的浮點數類型float和double不能夠進行運算,因為大多數情況下是正常的,但是偶爾會出現如上所示的問題。這個問題其實不是JAVA的bug,因為計算機本身是二進制的,而浮點數實際上隻是個近似值,是以從二進制轉化為十進制浮點數時,精度容易丢失,導緻精度下降。
出現的問題
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TP35kerRlT3lFVNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLzEzN1MzM0kDM3ATNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
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);