摘要
Java中的浮点数类型float和double不能够进行运算,因为大多数情况下是正常的,但是偶尔会出现如上所示的问题。这个问题其实不是JAVA的bug,因为计算机本身是二进制的,而浮点数实际上只是个近似值,所以从二进制转化为十进制浮点数时,精度容易丢失,导致精度下降。
出现的问题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);