一、构造BigDecimal对象
//将int/long/double/String类型的值转换为BigDecimal类型
//double的构造方法的结果有一定的不可预知性
BigDecimal valueBigdecimal = new BigDecimal(value);
二、BigDecimal的加、减、乘、除
1. BigDecimal加法:add(BigDecimal)
//举例
BigDecimal value = new BigDecimal(5);
BigDecimal addValue = value.add(new BigDecimal(3));
System.out.print(addValue);
//输出 8
2. BigDecimal减法:subtract(BigDecimal)
//举例
BigDecimal value = new BigDecimal(5);
BigDecimal subtractValue = value.subtract(new BigDecimal(3));
System.out.print(subtractValue);
//输出 2
3. BigDecimal乘法:multiply(BigDecimal)
//举例
BigDecimal value = new BigDecimal(5);
BigDecimal multiplyValue = value.multiply(new BigDecimal(3));
System.out.print(multiplyValue);
//输出 15
4. BigDecimal除法:divide(BigDecimal)
注意,除法需要定义保留小数位数和保留方式(详见三),否则有无限循环小数时会抛出异常
//举例
BigDecimal value = new BigDecimal(5);
//保留两位小数、两位后直接截取
BigDecimal divideValue = value.divide(new BigDecimal(3), 2, BigDecimal.ROUND_DOWN);
System.out.print(divideValue);
//输出 1.66
三、BigDecimal的小数保留方式
ROUND_UP 向远离0的方向舍入
ROUND_DOWN 向0方向舍入
ROUND_CEILING 向正无穷方向舍入
ROUND_FLOOR 向负无穷方向舍入
ROUND_HALF_UP 向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入(四舍五入)
ROUND_HALF_DOWN 向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入(五舍六入)
ROUND_HALF_EVEN 向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP ,如果是偶数,使用ROUND_HALF_DOWN
ROUND_UNNECESSARY 计算结果是精确的,不需要舍入模式
//举例 四舍五入保留两位小数
BigDecimal value = new BigDecimal(5.336);
BigDecimal valueRound = value.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.print(valueRound);
//输出 5.34
四、BigDecimal的常用方法
toString() BigDecimal->字符串
doubleValue() BigDecimal->double
floatValue() BigDecimal->float
longValue() BigDecimal->long
intValue() BigDecimal->int
compareTo() 比较两个BigDecimal类型的值的大小
五、写在最后(2020年9月27日更新)
Double转BigDecimal
很多人在使用new BigDeciaml(double)方法的时候都“深受其困”,0.3保留一位怎么变成了0.2?原因和解决办法都在源码里(不想看源码?直接下拉):
//将双精度型转换为BigDecimal,它是双精度型二进制浮点值的精确十进制表示形式。
Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value.
//返回的BigDecimal的小数位是最小值,因此小数位val是整数。
The scale of the returned BigDecimal is the smallest value such that scale val is an integer.
Notes:
//此构造函数的结果可能有些不可预测。
The results of this constructor can be somewhat unpredictable.
//可能有人假设用Java编写新的BigDecimal(0.1)会创建一个BigDecimal,它精确地等于0.1(未缩放的值1,小数位为1),但实际上等于0.1000000000000000055555511151231257827021181583404541015625。
One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625.
//这是因为0.1无法精确地表示为双精度(或就此而言,表示为任何有限长度的二进制分数)。
This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length).
//因此,尽管这样,但是传递给构造函数的值并不完全等于0.1。
Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
//另一方面,String构造函数是完全可预测的:就像期望的那样,编写新的BigDecimal(“ 0.1”)会创建一个完全等于0.1的BigDecimal。
The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect.
//因此,通常建议优先使用BigDecimal(String)String构造函数。
Therefore, it is generally recommended that the BigDecimal(String) String constructor be used in preference to this one.
//当必须将double用作BigDecimal的源时,请注意,此构造函数提供了精确的转换。
When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion;
//它与使用Double toString(double)方法然后使用BigDecimal(String)构造函数将double转换为String的结果不同。
it does not give the same result as converting the double to a String using the Double toString(double) method and then using the BigDecimal(String) constructor.
//要获得该结果,请使用静态valueOf(double)方法。
To get that result, use the static valueOf(double) method.
概括一下
原因:BigDecimal不靠谱
解决办法:new BigDecimal(Double.toString(double) )