由于BigDecimal 在处理的时候把十进制小数扩大 N 倍让它在整数上进行计算,并保留相应的精度信息。
①float 和 double 类型,主要是为了科学计算和工程计算而设计的,之所以执行二进制浮点运算,是为了在广泛的数值范围上提供较为精确的快速近和计算。
②并没有提供完全精确的结果,所以不应该被用于精确的结果的场合。
③当浮点数达到一定大的数,就会自动使用科学计数法,这样的表示只是近似真实数而不等于真实数。
④当十进制小数位转换二进制的时候也会出现无限循环或者超过浮点数尾数的长度。
所以,在涉及到精度计算的过程中,我们尽量使用 String 类型来进行转换。
可以借用一下工具类处理浮点型数值的计算:
package cn.com.xxx;
import java.math.BigDecimal;
/**
* * @ClassName: BigDecimalUtils
* * @Description 浮点型数值的精度计算工具类
* * @Author 逝者..
* * @Version 1.0
*/
public class BigDecimalUtils {
/**
* 两个Double类型数值相加
*
* @param v1 参数一
* @param v2 参数二
* @return
*/
public static BigDecimal doubleAdd(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2);
}
/**
* 两个Float类型数值相加
*
* @param v1 参数一
* @param v2 参数二
* @return
*/
public static BigDecimal floatAdd(float v1, float v2) {
BigDecimal b1 = new BigDecimal(Float.toString(v1));
BigDecimal b2 = new BigDecimal(Float.toString(v2));
return b1.add(b2);
}
/**
* 两个Double类型数值相减
*
* @param v1 参数一
* @param v2 参数二
* @return
*/
public static BigDecimal doubleSub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2);
}
/**
* 两个Float类型数值相减
*
* @param v1 参数一
* @param v2 参数二
* @return
*/
public static BigDecimal floatSub(float v1, float v2) {
BigDecimal b1 = new BigDecimal(Float.toString(v1));
BigDecimal b2 = new BigDecimal(Float.toString(v2));
return b1.subtract(b2);
}
/**
* 两个Double类型数值相乘
*
* @param v1 参数一
* @param v2 参数二
* @return
*/
public static BigDecimal doubleMul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2);
}
/**
* 两个Float类型数值相乘
*
* @param v1 参数一
* @param v2 参数二
* @return
*/
public static BigDecimal floatMul(float v1, float v2) {
BigDecimal b1 = new BigDecimal(Float.toString(v1));
BigDecimal b2 = new BigDecimal(Float.toString(v2));
return b1.multiply(b2);
}
/**
* 两个Double类型数值相除,保留小数点后两位后四舍五入
* v1/v2
*
* @param v1 参数一
* @param v2 参数二
* @return
*/
public static BigDecimal doubleDiv(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
// 保留小数点后两位 ROUND_HALF_UP = 四舍五入
return b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP);
}
/**
* 两个Float类型数值相除,保留小数点后两位后四舍五入
* v1/v2
*
* @param v1 参数一
* @param v2 参数二
* @return
*/
public static BigDecimal floatDiv(float v1, float v2) {
BigDecimal b1 = new BigDecimal(Float.toString(v1));
BigDecimal b2 = new BigDecimal(Float.toString(v2));
// 保留小数点后两位 ROUND_HALF_UP = 四舍五入
return b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP);
}
/**
* 比较Double类型数值v1 v2大小
*
* @param v1
* @param v2
* @return v1>v2 return 1; v1=v2 return 0;v1<v2 return -1
*/
public static int doubleCompareTo(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.compareTo(b2);
}
/**
* 比较Float类型数值v1 v2大小
*
* @param v1
* @param v2
* @return v1>v2 return 1; v1=v2 return 0;v1<v2 return -1
*/
public static int floatCompareTo(float v1, float v2) {
BigDecimal b1 = new BigDecimal(Float.toString(v1));
BigDecimal b2 = new BigDecimal(Float.toString(v2));
return b1.compareTo(b2);
}
}
运行结果: