# Java开发中商业计算请务必使用BigDecimal来进行计算！

2.

BigDecimal

BigDecimal表示不可变的任意精度带符号十进制数。它由两部分组成：

• intVal - 未校正精度的整数,类型为`BigInteger`
• Scale - 一个32位整数，表示小数点右边的位数

3.

```@Test
public void theValueMatches() {
BigDecimal bdFromString = new BigDecimal("0.12");
BigDecimal bdFromCharArray = new BigDecimal(new char[]{'3', '.', '1', '4', '1', '5'});
BigDecimal bdlFromInt = new BigDecimal(42);
BigDecimal bdFromLong = new BigDecimal(123412345678901L);
BigInteger bigInteger = BigInteger.probablePrime(100, new Random());
BigDecimal bdFromBigInteger = new BigDecimal(bigInteger);
assertEquals("0.12", bdFromString.toString());
assertEquals("3.1415", bdFromCharArray.toString());
assertEquals("42", bdlFromInt.toString());
assertEquals("123412345678901", bdFromLong.toString());
assertEquals(bigInteger.toString(), bdFromBigInteger.toString());
}```

```@Test
public void whenBigDecimalCreatedFromDouble_thenValueMayNotMatch() {
BigDecimal bdFromDouble = new BigDecimal(0.1d);
assertNotEquals("0.1", bdFromDouble.toString());
}```

```@Test
public void whenBigDecimalCreatedUsingValueOf_thenValueMatches() {
BigDecimal bdFromDouble = BigDecimal.valueOf(0.1d);
BigDecimal bigFromLong=BigDecimal.valueOf(1,1);

assertEquals("0.1", bdFromDouble.toString());
assertEquals("0.1", bigFromLong.toString());
}```

4.

`对应方法相关用法解释`

5.

BigDecimal操作

BigDecimal上的操作就像其他Number类（Integer，Long，Double等）一样，BigDecimal提供算术和比较操作的操作。它还提供了缩放操作，舍入和格式转换的操作。它不会使算术运算符(+ - /*)或逻辑运算符(> < | &) 过载。相反，我们使用`BigDecimal`相应的方法 - 加，减，乘，除和比较。并且`BigDecimal`具有提取各种属性的方法。

5.1

```@Test
public void whenGettingAttributes_thenExpectedResult() {
BigDecimal bd = new BigDecimal("-12345.6789");

assertEquals(9, bd.precision());
assertEquals(4, bd.scale());
assertEquals(-1, bd.signum());
}```

5.2

```@Test
public void whenComparingBigDecimals_thenExpectedResult() {
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("1.00");
BigDecimal bd3 = new BigDecimal("2.0");

assertTrue(bd1.compareTo(bd3) < 0);
assertTrue(bd3.compareTo(bd1) > 0);
assertTrue(bd1.compareTo(bd2) == 0);
assertTrue(bd1.compareTo(bd3) <= 0);
assertTrue(bd1.compareTo(bd2) >= 0);
assertTrue(bd1.compareTo(bd3) != 0);
}```

```@Test
public void whenEqualsCalled_thenSizeAndScaleMatched() {
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("1.00");

assertFalse(bd1.equals(bd2));
}```

5.3

BigDecimal 提供了以下四则运算的方法：

• subtract ——减法
• divide ——除法，有可能除不尽，必须显式声明保留小数位数避免抛出`ArithmeticException`异常
• multiply ——乘法
```@Test
public void whenPerformingArithmetic_thenExpectedResult() {
BigDecimal bd1 = new BigDecimal("4.0");
BigDecimal bd2 = new BigDecimal("2.0");

BigDecimal difference = bd1.subtract(bd2);
BigDecimal quotient = bd1.divide(bd2);
BigDecimal product = bd1.multiply(bd2);

assertTrue(sum.compareTo(new BigDecimal("6.0")) == 0);
assertTrue(difference.compareTo(new BigDecimal("2.0")) == 0);
assertTrue(quotient.compareTo(new BigDecimal("2.0")) == 0);
assertTrue(product.compareTo(new BigDecimal("8.0")) == 0);
}```

5.4

• RoundingMode.UP：以小数位为原点 是正数取右边，负数取左边
• RoundingMode.DOWN：以小数位为原点 也就是正数取左边，负数取右边
• RoundingMode.FLOOR：取左边最近的正数
• RoundingMode.CEILING：取右边最近的整数
• RoundingMode.HALF_DOWN:五舍六入，负数先取绝对值再五舍六入再负数
• RoundingMode.HALF_UP:四舍五入，负数原理同上
• RoundingMode.HALF_EVEN:这个比较绕，整数位若是奇数则四舍五入，若是偶数则五舍六入
• RoundingMode.ROUND_UNNECESSARY：不需要取整，如果存在小数位，就抛ArithmeticException 异常

6.

6.1

NumberFormat

• NumberFormat.getInstance(Locale)、getNumberInstance(Locale)。返回指定语言环境的通用数值格式。
• NumberFormat.getCurrencyInstance(Locale)。返回指定语言环境的货币格式。
• NumberFormat.getPercentInstance(Locale)。返回指定语言环境的百分比格式。
• NumberFormat.getIntegerInstance(Locale)。返回指定语言环境的整数数值格式。
• NumberFormat.setMinimumIntegerDigits(int)。设置数的整数部分所允许的最小位数。
• NumberFormat.setMaximumIntegerDigits(int)。设置数的整数部分所允许的最大位数。
• NumberFormat.setMinimumFractionDigits(int)。设置最少小数点位数，不足的位数以0补位，超出的话按实际位数输出。
• NumberFormat.setMaximumFractionDigits(int)。设置最多保留小数位数，不足不补0。

6.2

DecimalFormat

`DecimalFormat`除了能代理上面的`NumberFormat`以外，还提供了基于`pattern`字符串的格式化风格，有点类似格式化时间一样。我们来看看`pattern`的规则:

• “0”——表示一位数值，如没有，显示0。如“0000.0000”，整数位或小数位>4，按实际输出，<4整数位前面补0小数位后面补0，凑足4位。
• “#”——表示任意位数的整数。如没有，则不显示。在小数点位使用，只表示一位小数，超出部分四舍五入。如：“#”：无小数，小数部分四舍五入。“.#”：整数部分不变，一位小数，四舍五入。“.##”：整数部分不变，二位小数，四舍五入。
• “.”——表示小数点。注意一个pattern中只能出现一次，超过一次将格式化异常。
• “，”——与模式“0”一起使用，表示逗号。注意一定不能在小数点后用，否则格式化异常。

7.

0 条评论

• ### java随机数中的陷阱

随机数我们应该不陌生，业务中我们用它来生成验证码，或者对重复性要求不高的id，甚至我们还用它在年会上搞抽奖。今天我们来探讨一下这个东西。如果使用不当会引发一系列...

• ### 微服务下 Spring Boot Maven 工程依赖关系管理

最基本的 pom.xml 包含工程信息、Spring Boot 父工程、属性配置、依赖包、构建插件

• ### 分布式搜索引擎面试题（一）

Lucene是一套用于全文检索和搜索的开放源代码程序库。实际上lucene的功能很单一，说到底，就是你给它若干个字符串，然后它为你提供一个全文搜索服务，告诉你你...

• ### 【答疑解惑】Java中的高精度数字

前几天网友在群里有问BigDecimal能直接赋值吗？就像使用基本数据类型那样，答案是不能。 Java中的基本数据类型有的时候是不能满足实际编程需要的，特别是在...

• ### Java中的BigDecimal类你了解多少？

可以看到在Java中进行浮点数运算的时候，会出现丢失精度的问题。那么我们如果在进行商品价格计算的时候，就会出现问题。很有可能造成我们手中有0.06元，却无法购买...

• ### BigDecimal大小判断

equals源码： public boolean equals(Object anObject) {//name2传入equals方法，anObject指向n...

• ### Java-BigDecimal数据类型

我们知道在Java中有float和double类型，它们的主要设计目标是为了科学计算和工程计算。然而，它们没有提供完全精确的结果【因为其有限的有效位数】，所以不...

• ### 【刨根问底】BigDecimal 案例和部分源码分析

在咱们开发过程中很容易遇到计算的问题，普通计算其实也还好使用int、long、double、float基本上能应付。但是如果涉及到数据类型转后在处理等就不是很好...

• ### Java之BigDecimal详解

​ Java在java.math包中提供的API类BigDecimal，用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效...