我是靠谱客的博主 现实饼干,这篇文章主要介绍Double类型丢失精度的两种解决方案,现在分享给大家,希望可以做个参考。

1、继续使用Double类型

其实只要在计算时使用封装的工具类,继续使用Double类型精度也不会丢失;转换为BigDecimal时,构造函数采用String那一个。

复制代码
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package com.sugarppig.general.utils; import com.sugarppig.common.exception.GeneralException; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Arrays; import java.util.List; import java.util.Objects; /** * @author SugarPPig * @date 2020-12-09 16:05 * @decription Double 精确计算工具 */ public class DoubleArithUtil { /** * 提供精确加法计算的add方法 * * @param value1 * 被加数 * @param value2 * 加数 * @return 两个参数的和 */ public static double add(double value1, double value2) { BigDecimal b1 = new BigDecimal(String.valueOf(value1)); BigDecimal b2 = new BigDecimal(String.valueOf(value2)); return b1.add(b2).doubleValue(); } /** * 提供精确减法运算的sub方法 * * @param value1 * 被减数 * @param value2 * 减数 * @return 两个参数的差 */ public static double sub(double value1, double value2) { BigDecimal b1 = new BigDecimal(String.valueOf(value1)); BigDecimal b2 = new BigDecimal(String.valueOf(value2)); return b1.subtract(b2).doubleValue(); } /** * 提供精确乘法运算的mul方法 * * @param value1 * 被乘数 * @param value2 * 乘数 * @return 两个参数的积 */ public static Double mul(Double value1, Double value2) { if (value1 == null || value2 == null) { return 0d; } BigDecimal b1 = new BigDecimal(String.valueOf(value1)); BigDecimal b2 = new BigDecimal(String.valueOf(value2)); return b1.multiply(b2).doubleValue(); } /** * 提供精确的除法运算方法div * * @param value1 * 被除数 * @param value2 * 除数 * @param scale * 精确范围 * @return 两个参数的商,默认四舍五入 * @throws GeneralException */ public static Double div(double value1, double value2, int scale) { // 如果精确范围小于0,抛出异常信息 if (scale < 0) { throw new GeneralException("精确度不能小于0"); } if (value2 == 0) { return 0d; } BigDecimal b1 = new BigDecimal(String.valueOf(value1)); BigDecimal b2 = new BigDecimal(String.valueOf(value2)); return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue(); } /** * 计算多个值的乘积 */ public static Double muls(Double... args) { if (args.length < 2) { throw new GeneralException("参数至少为2个"); } List<Double> doubles = Arrays.asList(args); if (doubles.stream().anyMatch(Objects::isNull)) { return 0d; } return doubles.parallelStream().reduce(1d, DoubleArithUtil::mul); } /** * 计算多个值的和 */ public static Double adds(Double... args) { if (args.length < 2) { throw new GeneralException("参数至少为2个"); } List<Double> doubles = Arrays.asList(args); if (doubles.stream().anyMatch(Objects::isNull)) { return 0d; } return doubles.parallelStream().reduce(0d, DoubleArithUtil::add); } /** * 计算多个值的和,元素为null时记为0d参与运算 */ public static Double addsNull(Double... args) { if (args.length < 2) { throw new GeneralException("参数至少为2个"); } List<Double> doubles = Arrays.asList(args); return doubles.parallelStream().map(e -> e == null ? 0d : e).reduce(0d, DoubleArithUtil::add); } }

2、将Double类型改为BigDecimal类型

BigDecimal工具类,将Double的工具类稍微改动了下。

复制代码
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package com.sugarppig.general.utils; import com.sugarppig.common.exception.GeneralException; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Arrays; import java.util.List; import java.util.Objects; /** * @author SugarPPig * @date 2020-12-10 10:03 * @decription BigDecimal 精确计算工具 */ public class BigDecimalArithUtil { /** * 提供精确加法计算的add方法 * * @param value1 * 被加数 * @param value2 * 加数 * @return 两个参数的和 */ public static BigDecimal add(BigDecimal value1, BigDecimal value2) { return value1.add(value2); } /** * 提供精确减法运算的sub方法 * * @param value1 * 被减数 * @param value2 * 减数 * @return 两个参数的差 */ public static BigDecimal sub(BigDecimal value1, BigDecimal value2) { return value1.subtract(value2); } /** * 提供精确乘法运算的mul方法 * * @param value1 * 被乘数 * @param value2 * 乘数 * @return 两个参数的积 */ public static BigDecimal mul(BigDecimal value1, BigDecimal value2) { if (value1 == null || value2 == null) { return BigDecimal.ZERO; } return value1.multiply(value2); } /** * 提供精确的除法运算方法div * * @param value1 * 被除数 * @param value2 * 除数 * @param scale * 精确范围 * @return 两个参数的商,默认四舍五入 * @throws GeneralException */ public static BigDecimal div(BigDecimal value1, BigDecimal value2, int scale) { // 如果精确范围小于0,抛出异常信息 if (scale < 0) { throw new GeneralException("精确度不能小于0"); } if (value2.compareTo(BigDecimal.ZERO) == 0) { return BigDecimal.ZERO; } return value1.divide(value2, scale, RoundingMode.HALF_UP); } /** * 计算多个值的乘积 */ public static BigDecimal muls(BigDecimal... args) { if (args.length < 2) { throw new GeneralException("参数至少为2个"); } List<BigDecimal> bigDecimals = Arrays.asList(args); if (bigDecimals.stream().anyMatch(Objects::isNull)) { return BigDecimal.ZERO; } return bigDecimals.parallelStream().reduce(BigDecimal.ONE, ArithUtil::mul); } /** * 计算多个值的和 */ public static BigDecimal adds(BigDecimal... args) { if (args.length < 2) { throw new GeneralException("参数至少为2个"); } List<BigDecimal> BigDecimals = Arrays.asList(args); if (BigDecimals.stream().anyMatch(Objects::isNull)) { return BigDecimal.ZERO; } return BigDecimals.parallelStream().reduce(BigDecimal.ZERO, ArithUtil::add); } /** * 计算多个值的和,元素为null时记为0参与运算 */ public static BigDecimal addsNull(BigDecimal... args) { if (args.length < 2) { throw new GeneralException("参数至少为2个"); } List<BigDecimal> BigDecimals = Arrays.asList(args); return BigDecimals.parallelStream().map(e -> e == null ? BigDecimal.ZERO : e).reduce(BigDecimal.ZERO, ArithUtil::add); } }

注意!!!使用BigDecimal比较两个数,值的大小时,一定要使用compareTo,不要用equals,源码显示它会检查小数位数是否相等。
在这里插入图片描述
测试两种比较方式的区别
测试

最后

以上就是现实饼干最近收集整理的关于Double类型丢失精度的两种解决方案的全部内容,更多相关Double类型丢失精度内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(70)

评论列表共有 0 条评论

立即
投稿
返回
顶部