java中使用BigDecimal
来表示价格是比较好的
1、为什么不使用double呢?
看一个例子:
double a1 = 0.03;
double a2 = 0.02;
double a3 = a1-a2;
System.out.println(a3);
结果:
0.009999999999999998
结论:
理论上来说双精度浮点型变量double可以处理16位有效数。但是在实际应用中,需要对更大或者更小的数进行运算和处理,所以float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal
2、BigDecimal定义
new BigDecimal()方法里面可以放int、Long、double、String四种类型,但是不建议用double,为什么呢,看下面的例子:
BigDecimal b1 = new BigDecimal(0.03);
System.out.println(b1);
结果:
0.0299999999999999988897769753748434595763683319091796875
解决double类型数据显示异常:
方案1:BigDecimal b1 = new BigDecimal(“0.03”);
方案2:BigDecimal b2 = BigDecimal.valueOf(0.03);
方案3:BigDecimal b3 = new BigDecimal(Double.toString(0.03));
3、BigDecimal加减乘除运算
和平常的+、-、*、/不同,BigDecimal使用方法来完成加减乘除运算,例子如下:
BigDecimal c1 = new BigDecimal("0.04");
BigDecimal c2 = new BigDecimal("0.03");
System.out.println(c1.add(c2));
System.out.println(c1.subtract(c2));
System.out.println(c1.multiply(c2));
System.out.println(c1.divide(c2,2,BigDecimal.ROUND_HALF_UP)); // 四舍五入
结果:
0.07
0.01
0.0012
1.34
注意点:
需要注意的是除法运算,BigDecimal除法可能出现不能整除的情况,比如 4.5/1.3,这时会报错java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result
解决除法异常:
其实divide方法有可以传三个参数:public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) 第一个参数表示除数, 第二个参数表示小数点后保留位数,第三个参数表示舍入模式,只有在作除法运算或四舍五入时才用到舍入模式,有下面这几种:
使用方法是BigDecimal.名称,通过设置小数点后保留位数可以解决除法异常问题,当然你也可以使用第三个参数去设置舍入模式来更好的达到你的要求
4、比较BigDecimal类型数据的大小
当然也不是使用普通的大于小于进行比较的,它使用的是compareTo()方法,例子如下:
BigDecimal d1 = new BigDecimal(3);
BigDecimal d2 = new BigDecimal(-5);
if (d1.compareTo(d2) == 1){
System.out.println(d1+"大于"+d2);
} else if (d1.compareTo(d2) == 0){
System.out.println(d1+"等于"+d2);
} else if (d1.compareTo(d2) == -1){
System.out.println(d1+"小于"+d2);
}
结果:
3大于-5
解释:
很明显的,就不解释了哈
5、设置小数的位数
简单介绍上面那张图片中的几种,例子如下:
BigDecimal e1 = new BigDecimal("1.345232589525852");
System.out.println("保留2位小数,直接删除多余的小数位数,然后进一位:"+e1.setScale(2,BigDecimal.ROUND_UP));
System.out.println("保留2位小数,直接删除多余的小数位数:"+e1.setScale(2,BigDecimal.ROUND_DOWN));
System.out.println("保留2位小数,四舍五入:"+e1.setScale(2,BigDecimal.ROUND_HALF_UP));
结果:
保留2位小数,直接删除多余的小数位数,然后进一位:1.35
保留2位小数,直接删除多余的小数位数:1.34
保留2位小数,四舍五入:1.35
6、格式化BigDecimal对象
也就是使用format(),但是要定义相应的对象来调用其中的format()方法,例子如下:
BigDecimal f1 = new BigDecimal("12987653421987652312");
BigDecimal f2 = new BigDecimal("0.0876525226");
// 建立货币格式化引用
NumberFormat currency = NumberFormat.getCurrencyInstance();
// 建立百分比格式化引用
NumberFormat percent = NumberFormat.getPercentInstance();
// 设置百分比小数点最多3位
percent.setMaximumFractionDigits(3);
System.out.println("currency形式:"+currency.format(f1));
System.out.println("percent形式:"+percent.format(f2));
结果:
currency形式:¥12,987,653,421,987,652,312.00
percent形式:8.765%
7、mysql中表示金钱用什么?
在数据库中不使用BigDecimal,而是使用decimal