我是靠谱客的博主 无限导师,这篇文章主要介绍new BigDecmal (double)精度问题及与BigDecimal.valueOf(double)的区别,现在分享给大家,希望可以做个参考。

工作时,有人用new BigDecmal (double)的方式计算精确数值,发现会有精度缺失的问题,改用BigDecimal.valueOf(double)的方式便好了,于是看了下两个源码。

 

1、new BigDecmal (double)源码

在传入double的时候,没有经过先转为string再进行转换,会有精度缺失的问题,源码的注释上也注明了这一点,追求精度的用valueOf方法或是可先将double 转为String然后用new BigDecmal (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
/** * Translates a {@code double} into a {@code BigDecimal} which * is the exact decimal representation of the {@code double}'s * binary floating-point value. The scale of the returned * {@code BigDecimal} is the smallest value such that * <tt>(10<sup>scale</sup> &times; val)</tt> is an integer. * <p> * <b>Notes:</b> * <ol> * <li> * The results of this constructor can be somewhat unpredictable. * One might assume that writing {@code new BigDecimal(0.1)} in * Java creates a {@code BigDecimal} which is exactly equal to * 0.1 (an unscaled value of 1, with a scale of 1), but it is * actually equal to * 0.1000000000000000055511151231257827021181583404541015625. * This is because 0.1 cannot be represented exactly as a * {@code double} (or, for that matter, as a binary fraction of * any finite length). Thus, the value that is being passed * <i>in</i> to the constructor is not exactly equal to 0.1, * appearances notwithstanding. * * <li> * The {@code String} constructor, on the other hand, is * perfectly predictable: writing {@code new BigDecimal("0.1")} * creates a {@code BigDecimal} which is <i>exactly</i> equal to * 0.1, as one would expect. Therefore, it is generally * recommended that the {@linkplain #BigDecimal(String) * <tt>String</tt> constructor} be used in preference to this one. * * <li> * When a {@code double} must be used as a source for a * {@code BigDecimal}, note that this constructor provides an * exact conversion; it does not give the same result as * converting the {@code double} to a {@code String} using the * {@link Double#toString(double)} method and then using the * {@link #BigDecimal(String)} constructor. To get that result, * use the {@code static} {@link #valueOf(double)} method. * </ol> * * @param val {@code double} value to be converted to * {@code BigDecimal}. * @throws NumberFormatException if {@code val} is infinite or NaN. */ public BigDecimal(double val) { this(val,MathContext.UNLIMITED); }

2、BigDecimal.valueOf(double)源码

可以看出,该方法先将double转为string然后用new BigDecmal (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
/** * Translates a {@code double} into a {@code BigDecimal}, using * the {@code double}'s canonical string representation provided * by the {@link Double#toString(double)} method. * * <p><b>Note:</b> This is generally the preferred way to convert * a {@code double} (or {@code float}) into a * {@code BigDecimal}, as the value returned is equal to that * resulting from constructing a {@code BigDecimal} from the * result of using {@link Double#toString(double)}. * * @param val {@code double} to convert to a {@code BigDecimal}. * @return a {@code BigDecimal} whose value is equal to or approximately * equal to the value of {@code val}. * @throws NumberFormatException if {@code val} is infinite or NaN. * @since 1.5 */ public static BigDecimal valueOf(double val) { // Reminder: a zero double returns '0.0', so we cannot fastpath // to use the constant ZERO. This might be important enough to // justify a factory approach, a cache, or a few private // constants, later. return new BigDecimal(Double.toString(val)); }

 

最后

以上就是无限导师最近收集整理的关于new BigDecmal (double)精度问题及与BigDecimal.valueOf(double)的区别的全部内容,更多相关new内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部