Java之BigDecimal

参考网站:java精确除法运算(BigDecimal)_bigdecimal 除法_Evan_su的博客-CSDN博客

一、BigDecimal 介绍

Java 中提供了大数字(超过 16 位有效位)的操作类,即 java.math.BinInteger 类和 java.math.BigDecimal 类,用于高精度计算。

其中 BigInteger 类是针对大整数的处理类,而 BigDecimal 类则是针对大小数的处理类。

BigDecimal 类的实现用到了 BigInteger 类,不同的是 BigDecimal 加入了小数的概念。

float 和 Double 只能用来做科学计算或者是工程计算;在商业计算中,对数字精度要求较高,必须使用 BigInteger 类和 BigDecimal 类,它支持任何精度的定点数,可以用它来精确计算货币值。

BigDecimal 类创建的是对象,不能使用传统的 +、-、*、/ 等算术运算符直接对其进行数学运算,而必须调用其对应的方法。方法的参数也必须是 BigDecimal 类型的对象。

二、BigDecimal 构造方法

1
2
3
4
5
6
7
8
// 方法一:不允许使用
BigDecimal BigDecimal(double d);

// 方法二:常用,推荐使用
BigDecimal BigDecimal(String s);

// 方法三:常用,推荐使用
static BigDecimal valueOf(double d);

注意:

  1. double 参数的构造方法,不允许使用!!!!因为它不能精确的得到相应的值,值会变大
  2. String 构造方法是完全可预知的:写入 new BigDecimal(“0.1”) 将创建一个 BigDecimal,它正好等于预期的 0.1;因此,通常建议优先使用 String 构造方法
  3. 静态方法 valueOf(double val) 内部实现,仍是将 double 类型转为 String 类型;这通常是将 double(或 float)转化为 BigDecimal 的首选方法

三、BigDecimal 类型转换

1
2
3
4
5
toString()    // 将 BigDecimal 对象的数值转换成字符串
doubleValue() // 将 BigDecimal 对象中的值以双精度数返回
floatValue() // 将 BigDecimal 对象中的值以单精度数返回
longValue() // 将 BigDecimal 对象中的值以长整数返回
intValue() // 将 BigDecimal 对象中的值以整数返回

四、BigDecimal 常用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 加法,求两个 BigDecimal 类型数据的和
BigDecimal add(BigDecimal value);
// 减法,求两个 BigDecimal 类型数据的差
BigDecimal subtract(BigDecimal value);
// 乘法,求两个 BigDecimal 类型数据的积
BigDecimal multiply(BigDecimal value);
// 除法,求两个 BigDecimal 类型数据的商
BigDecimal divide(BigDecimal divisor);
// 求余数,求 BigDecimal 类型数据除以 divisor 的余数
BigDecimal remainder(BigDecimal divisor);
// 最大数,求两个 BigDecimal 类型数据的最大值
BigDecimal max(BigDecimal value);
// 最小数,求两个 BigDecimal 类型数据的最小值
BigDecimal min(BigDecimal value);
// 绝对值,求 BigDecimal 类型数据的绝对值
BigDecimal abs();
// 相反数,求 BigDecimal 类型数据的相反数
BigDecimal negate();

五、BigDecimal.divide()

1
2
3
4
5
6
7
8
9
10
/**
* @param divisor 除数
* @param scale 小数点后保留位数
* @param roundingMode 取舍规则
*/
BigDecimal.divide(BigDecimal divisor, int scale, RoundingMode roundingMode);

bd2.divide(bd1, 4, BigDecimal.ROUND_HALF_UP).toString(); // "0.0200"
// 商的小数点后位数是固定的,如果需要去除末尾多余的0,则使用下面方法
bd2.divide(bd1, 4, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString(); // "0.02"

因为 BigDecimal 除法可能出现不能整除的情况,比如 4.5/1.3,这时会报错【java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result】。所以就需要用三个参数的除法方法,规定保留几位小数以及保留的方式,这样就可以避免异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
*ROUND_CEILING*
Rounding mode to round towards positive infinity.
向正无穷方向舍入
正数:1.1 -> 2 1.5-> 2 1.8-> 2
负数:-1.1-> -1 -1.5-> -1 -1.8-> -1

*ROUND_DOWN*
Rounding mode to round towards zero.
向零方向舍入
正数:1.1 -> 2 1.5-> 2 1.8-> 2
负数:-1.1-> -1 -1.5-> -1 -1.8-> -1

*ROUND_FLOOR*
Rounding mode to round towards negative infinity.
向负无穷方向舍入
正数: 1.1-> 1 1.5-> 1 1.8-> 1
负数: -1.1-> -2 -1.5-> -2 -1.8-> -2

*ROUND_HALF_DOWN*
Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.
向(距离)最近的一边舍入,除非两边(的距离)是相等。如果是这样,向下舍入, 例如 1.55 保留一位小数结果为 1.5
正数:1.5-> 1 1.6-> 2
负数:-1.5-> -1 -1.6-> -2

*ROUND_HALF_EVEN*
Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor.
向(距离)最近的一边舍入,除非两边(的距离)是相等。如果是这样,如果保留位数是奇数,使用 ROUND_HALF_UP,如果是偶数,使用*ROUND_HALF_DOWN*(以 5 为分界线,如果是 5,则前一位变偶数)
1.15-> 1.2 1.16-> 1.2 1.25-> 1.2 1.26-> 1.3

*ROUND_HALF_UP*
Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.
向(距离)最近的一边舍入,除非两边(的距离)是相等。如果是这样,向上舍入, 1.55 保留一位小数结果为 1.6
【四舍五入】

*ROUND_UNNECESSARY*
Rounding mode to assert that the requested operation has an exact result, hence no rounding is necessary.
计算结果是精确的,不需要舍入模式

*ROUND_UP*
Rounding mode to round away from zero.
向远离 0 的方向舍入
正数:1.1-> 2 1.5-> 2 1.8-> 2
负数:-1.1-> -2 -1.5-> -2 -1.8-> -2

六、BigDecimal.setScale()

1
2
3
4
5
BigDecimal setScale(int newScale, RoundingMode roundingMode);

BigDecimal setScale(int newScale, int roundingMode);

BigDecimal setScale(int newScale);
1
2
3
4
5
6
7
8
public class TestBigDecimal {
public static void main(String[] args) {
BigDecimal b1 = new BigDecimal("123.564");
BigDecimal b2 = new BigDecimal("3.3");
BigDecimal divide = b1.divide(b2, 10, RoundingMode.HALF_UP);
System.out.println(divide);
}
}





  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2024 Liangxj
  • 访问人数: | 浏览次数: