Skip to content

Commit 80d9e98

Browse files
committed
[docs improve]java基础部分内容完善
1 parent 689d00f commit 80d9e98

File tree

3 files changed

+164
-75
lines changed

3 files changed

+164
-75
lines changed

docs/java/basis/bigdecimal.md

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,7 @@ tag:
77

88
《阿里巴巴 Java 开发手册》中提到:“为了避免精度丢失,可以使用 `BigDecimal` 来进行浮点数的运算”。
99

10-
这篇文章,我就简单解释一下浮点数运算出现精度丢失的原因以及 `BigDecimal` 的常见用法,希望对大家有帮助!
11-
12-
## BigDecimal 介绍
13-
14-
`BigDecimal` 可以实现对浮点数的运算,不会造成精度丢失。通常情况下,大部分需要浮点数精确运算结果的业务场景(比如涉及到钱的场景)都是通过 `BigDecimal` 来做的。
15-
16-
纳尼,浮点数的运算竟然还会有精度丢失的风险吗?确实会!
10+
浮点数的运算竟然还会有精度丢失的风险吗?确实会!
1711

1812
示例代码:
1913

@@ -44,25 +38,19 @@ System.out.println(a == b);// false
4438

4539
关于浮点数的更多内容,建议看一下[计算机系统基础(四)浮点数](http://kaito-kidd.com/2018/08/08/computer-system-float-point/)这篇文章。
4640

47-
## BigDecimal 的用处
41+
## BigDecimal 介绍
4842

49-
《阿里巴巴 Java 开发手册》中提到:**浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用 equals 来判断。**
43+
`BigDecimal` 可以实现对浮点数的运算,不会造成精度丢失。
5044

51-
![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/image-20211213101646884.png)
45+
通常情况下,大部分需要浮点数精确运算结果的业务场景(比如涉及到钱的场景)都是通过 `BigDecimal` 来做的。
5246

53-
具体原因我们在上面已经详细介绍了,这里就不多提了,我们下面直接上实例:
47+
《阿里巴巴 Java 开发手册》中提到:**浮点数之间的等值判断,基本数据类型不能用 == 来比较,包装数据类型不能用 equals 来判断。**
5448

55-
```java
56-
float a = 1.0f - 0.9f;
57-
float b = 0.9f - 0.8f;
58-
System.out.println(a);// 0.100000024
59-
System.out.println(b);// 0.099999964
60-
System.out.println(a == b);// false
61-
```
49+
![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/image-20211213101646884.png)
6250

63-
从输出结果就可以看出发生精度丢失的问题
51+
具体原因我们在上面已经详细介绍了,这里就不多提了
6452

65-
想要解决这个问题也很简单,直接使用 `BigDecimal` 来定义浮点数的值,再进行浮点数的运算操作即可
53+
想要解决浮点数运算精度丢失这个问题,可以直接使用 `BigDecimal` 来定义浮点数的值,然后再进行浮点数的运算操作即可
6654

6755
```java
6856
BigDecimal a = new BigDecimal("1.0");
@@ -72,13 +60,19 @@ BigDecimal c = new BigDecimal("0.8");
7260
BigDecimal x = a.subtract(b);
7361
BigDecimal y = b.subtract(c);
7462

75-
System.out.println(x); /* 0.1 */
76-
System.out.println(y); /* 0.1 */
77-
System.out.println(Objects.equals(x, y)); /* true */
63+
System.out.println(x.compareTo(y));// 0
7864
```
7965

8066
## BigDecimal 常见方法
8167

68+
### 创建
69+
70+
我们在使用 `BigDecimal` 时,为了防止精度丢失,推荐使用它的`BigDecimal(String val)`构造方法或者 `BigDecimal.valueOf(double val)` 静态方法来创建对象。
71+
72+
《阿里巴巴 Java 开发手册》对这部分内容也有提到,如下图所示。
73+
74+
![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/image-20211213102222601.png)
75+
8276
### 加减乘除
8377

8478
`add` 方法用于将两个 `BigDecimal` 对象相加,`subtract` 方法用于将两个 `BigDecimal` 对象相减。`multiply` 方法用于将两个 `BigDecimal` 对象相乘,`divide` 方法用于将两个 `BigDecimal` 对象相除。
@@ -144,13 +138,33 @@ BigDecimal n = m.setScale(3,RoundingMode.HALF_DOWN);
144138
System.out.println(n);// 1.255
145139
```
146140

147-
## BigDecimal 的使用注意事项
141+
## BigDecimal 等值比较问题
148142

149-
注意:我们在使用 `BigDecimal` 时,为了防止精度丢失,推荐使用它的`BigDecimal(String val)`构造方法或者 `BigDecimal.valueOf(double val)` 静态方法来创建对象。
143+
《阿里巴巴 Java 开发手册》中提到:
150144

151-
《阿里巴巴 Java 开发手册》对这部分内容也有提到,如下图所示。
145+
![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/image-20220714161315993.png)
152146

153-
![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/javaguide/image-20211213102222601.png)
147+
`BigDecimal` 使用 `equals()` 方法进行等值比较出现问题的代码示例:
148+
149+
```java
150+
BigDecimal a = new BigDecimal("1");
151+
BigDecimal b = new BigDecimal("1.0");
152+
System.out.println(a.equals(b));//false
153+
```
154+
155+
这是因为 `equals()` 方法不仅仅会比较值的大小(value)还会比较精度(scale),而 `compareTo()` 方法比较的时候会忽略精度。
156+
157+
1.0 的 scale 是 1,1 的 scale 是 0,因此 `a.equals(b)` 的结果是 false。
158+
159+
![](https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/image-20220714164706390.png)
160+
161+
`compareTo()` 方法可以比较两个 `BigDecimal` 的值,如果相等就返回 0,如果第 1 个数比第 2 个数大则返回 1,反之返回-1。
162+
163+
```java
164+
BigDecimal a = new BigDecimal("1");
165+
BigDecimal b = new BigDecimal("1.0");
166+
System.out.println(a.compareTo(b));//0
167+
```
154168

155169
## BigDecimal 工具类分享
156170

@@ -342,4 +356,3 @@ public class BigDecimalUtil {
342356
浮点数没有办法用二进制精确表示,因此存在精度丢失的风险。
343357

344358
不过,Java 提供了`BigDecimal` 来操作浮点数。`BigDecimal` 的实现利用到了 `BigInteger` (用来操作大整数), 所不同的是 `BigDecimal` 加入了小数位的概念。
345-

0 commit comments

Comments
 (0)