我是靠谱客的博主 温柔枫叶,这篇文章主要介绍Java Double类型精确运算解决,现在分享给大家,希望可以做个参考。

Java中的简单浮点数类型float和double不能够进行运算。

首先我们想到的是四舍五入,Math类中的round方法不能设置保留几位小数,我们只能像这样(例如保留两位)

复制代码
1
Math.round(value * 100) / 100.0;

非常不幸,上面的代码不能解决包含小数位精度问题,类似400.0000000009,或者整数差0.00000000001的问题。

其次我们会使用BigDecimal,使用他的4个构造方法即加、减、乘、除。

当然想到这里,也差不多能解决上面的问题了

解决方案:

复制代码
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
131
132
133
134
135
import java.math.BigDecimal; import java.text.DecimalFormat; import java.util.regex.Pattern; public final strictfp class MathUtil { private MathUtil() { } // 默认运算精度 private static int DEF_SCALE = 10; /** * 提供数据类型转换为BigDecimal * * @param object 原始数据 * @return BigDecimal */ public static final BigDecimal bigDecimal(Object object) { if (object == null) { throw new NullPointerException(); } BigDecimal result; try { result = new BigDecimal(String.valueOf(object).replaceAll(",", "")); } catch (NumberFormatException e) { throw new NumberFormatException("Please give me a numeral.Not " + object); } return result; } /** * 提供(相对)精确的加法运算。 * * @param num1 被加数 * @param num2 加数 * @return 两个参数的和 */ public static final Double add(Object num1, Object num2) { BigDecimal result = bigDecimal(num1).add(bigDecimal(num2)); return result.setScale(DEF_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供(相对)精确的减法运算。 * * @param num1 被减数 * @param num2 减数 * @return 两个参数的差 */ public static final Double subtract(Object num1, Object num2) { BigDecimal result = bigDecimal(num1).subtract(bigDecimal(num2)); return result.setScale(DEF_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供(相对)精确的乘法运算。 * * @param num1 被乘数 * @param num2 乘数 * @return 两个参数的积 */ public static final Double multiply(Object num1, Object num2) { BigDecimal result = bigDecimal(num1).multiply(bigDecimal(num2)); return result.setScale(DEF_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供(相对)精确的除法运算,当发生除不尽的情况时,精度为10位,以后的数字四舍五入。 * * @param num1 被除数 * @param num2 除数 * @return 两个参数的商 */ public static final Double divide(Object num1, Object num2) { return divide(num1, num2, DEF_SCALE); } /** * 提供(相对)精确的除法运算。 当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入。 * * @param num1 被除数 * @param num2 除数 * @param scale 表示表示需要精确到小数点以后几位。 * @return 两个参数的商 */ public static final Double divide(Object num1, Object num2, Integer scale) { if (scale == null) { scale = DEF_SCALE; } num2 = num2 == null || Math.abs(new Double(num2.toString())) == 0 ? 1 : num2; if (scale < 0) { throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal result = bigDecimal(num1).divide(bigDecimal(num2), scale, BigDecimal.ROUND_HALF_UP); return result.doubleValue(); } /** * 提供精确的小数位四舍五入处理。 * * @param num 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static final Double round(Object num, int scale) { if (scale < 0) { throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal result = bigDecimal(num).divide(bigDecimal("1"), scale, BigDecimal.ROUND_HALF_UP); return result.doubleValue(); } /** * 获取start到end区间的随机数,不包含start+end * * @param start * @param end * @return */ public static final BigDecimal getRandom(int start, int end) { return new BigDecimal(start + Math.random() * end); } /** * 格式化 * * @param obj * @param pattern * @return */ public static final String format(Object obj, String pattern) { if (obj == null) { return null; } if (pattern == null || "".equals(pattern)) { pattern = "#"; } DecimalFormat format = new DecimalFormat(pattern); return format.format(bigDecimal(obj)); } /** 是否数字 */ public static final boolean isNumber(Object object) { Pattern pattern = Pattern.compile("\d+(.\d+)?$"); return pattern.matcher(object.toString()).matches(); }

这里需要将结果round再次保留2位小数

复制代码
1
MathUtil.round(MathUtil.add("100.03", "232.134"), 2);

以上解决Java Double精确运算的问题。

最后

以上就是温柔枫叶最近收集整理的关于Java Double类型精确运算解决的全部内容,更多相关Java内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部