0x00 问题
今天发现组内新人使用BigDecimal的构造函数,将double类型转为BigDecimal类型。结果,悲剧了!如下:
Double d = 0.1;
System.out.println(d); // 0.1
BigDecimal bd = new BigDecimal(d);
System.out.println(bd); // 0.1000000000000000055511151231257827021181583404541015625
眼前的0.1并不是你碎碎念的0.1了...怎么解决呢?
0x01 解决方案
可以使用BigDecimal.valueOf(double),代码如下:
Double d = 0.1;
System.out.println(d); // 0.1
BigDecimal bds = BigDecimal.valueOf(d);
System.out.println(bds); // 0.1
0x02 new BigDecimal(double) vs BigDecimal.valueOf(double)
new BigDecimal(double)
Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value. The scale of the returned BigDecimal is the smallest value such that (10scale × val) is an integer.
Notes:
- The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a 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 double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
- The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.
- When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method.
将double转换为BigDecimal ,这是double的二进制浮点值的精确十进制表示。 返回的BigDecimal是(10scale × val)是一个整数的最小值。
需要注意的是:
- 这个构造函数的结果可能有些不可预测。 可以假设在Java中写入new BigDecimal(0.1)创建一个BigDecimal ,它完全等于0.1(非标尺值为1,比例为1),但实际上等于0.1000000000000000055511151231257827021181583404541015625。 这是因为0.1不能像double (或者作为任何有限长度的二进制分数)精确地表示。 因此,正在被传递给构造的值不是正好等于0.1,虽然表面上。
- 该String构造,在另一方面,是完全可以预测的:写new BigDecimal("0.1")创建BigDecimal这正好等于0.1,正如人们所期望的那样。 因此, 一般建议使用String constructor优先于此。
- 当double必须用作源为BigDecimal ,注意,此构造提供了一个精确的转换; 它不会将double转换为String使用Double.toString(double)方法,然后使用BigDecimal(String)构造函数相同的结果。 要获得该结果,请使用static valueOf(double)方法。
BigDecimal.valueOf(double)
Translates a double into a BigDecimal, using the double's canonical string representation provided by the Double.toString(double) method.
Note: This is generally the preferred way to convert a double (or float) into a BigDecimal, as the value returned is equal to that resulting from constructing a BigDecimal from the result of using Double.toString(double).
转换一个double成BigDecimal ,使用double通过所提供的规范的字符串表示Double.toString(double)方法。
注意:这通常是转换的首选方法double (或float )成BigDecimal ,作为返回的值等于从构建所得BigDecimal使用的结果Double.toString(double) 。
大概不需要多解释了把?
0x03 多说一句
任何技术/工具,用之前请先阅读一下官方文档,就像吃药之前看一下遗嘱或者说明书一样,相同的道理。
下课!