一、原因
在涉及有关金钱的时候,数据类型一般不用 Float 或 Double。原因如下:
public static void main(String[] args) {
double a1 = 0.2;
double a2 = 0.3;
double a3 = a2 - a1;
System.out.println(a3);
}
结果你猜猜,0.1对吧!没错,你可真聪明!
其实答案是~
如果用float 或 double经常会有这样的情况,精度缺失,因为都是浮点数呀(复杂,这个我解释不清,有兴趣可以百度百度哦!)
二、BigDecimal登场啦
金额必须是完全精确的计算, 故不能使用double或者float, 而应该采用java.math.BigDecimal.
BigDecimal的范围大、精度高,最适合用来计算金额了。BigDecimal 这种类型,对应数据库中的decimal类型。
money decimal(18,2) DEFAULT '0.00' COMMENT '账户余额',
接下来,记录一下它的用法:
(1)加减乘除
BigDecimal的加减乘除可不是平时的 +、-、*、/ ,它是使用了英文的加减乘除, 即add, substract, multiply和divide
public static void main(String[] args) {
BigDecimal num1 = new BigDecimal("0.2");
BigDecimal num2 = new BigDecimal("0.3");
System.out.println(num1.add(num2));// 加法:0.5
System.out.println(num1.subtract(num2));// 减法:-0.1
System.out.println(num1.multiply(num2));// 乘法:0.06
System.out.println(num1.divide(num2, RoundingMode.HALF_DOWN));// 除法:0.7(四舍五入)
}
}
(2)大小比较
两个数的大小比较也不是用 ‘ < ’、' > ' ,两个BigDecimal值比较使用compareTo方法, 比较结果有-1, 0, 1, 分别表示小于, 等于, 大于; 对于0, 可以使用BigDecimal.ZERO表示。
public static void main(String[] args) {
BigDecimal num1 = new BigDecimal("0.2");
BigDecimal num2 = new BigDecimal("0.3");
System.out.println(num1.compareTo(num2));
System.out.println(num2.compareTo(num1));
if (num1.compareTo(BigDecimal.ZERO) == -1) {
System.out.println("num1 < 0");
} else if (num1.compareTo(BigDecimal.ZERO) == 1) {
System.out.println("num1 > 0");
} else if (num1.compareTo(BigDecimal.ZERO) == 0) {
System.out.println("num1 = 0");
}
}
(3)控制小数范围
public static void main(String[] args) {
BigDecimal amount = new BigDecimal("80");
BigDecimal num = amount.multiply(new BigDecimal(0.09 / 1.09));
System.out.println(num);
// 6.60550458715596255920843304920708760619163513183593750000
System.out.println("ROUND_DOWN模式 : " + num.setScale(2, BigDecimal.ROUND_DOWN));
//6.60,直接删除多余的小数
System.out.println("ROUND_UP模式 : " + num.setScale(2, BigDecimal.ROUND_UP));
//6.61,直接进位删除
System.out.println("ROUND_HALF_UP模式 : " + num.setScale(2, BigDecimal.ROUND_HALF_UP));
//6.61,四舍五入,碰到5进位
System.out.println("ROUND_HALF_DOWN模式 : " + num.setScale(2, BigDecimal.ROUND_HALF_DOWN));
//6.61,四舍五入,碰到5舍弃
}