Java的 BigDecimal 怎么会这么痛苦?
双d = 13.3D; BigDecimal bd1 = new BigDecimal(d); BigDecimal bd2 = new BigDecimal(String.valueOf(d)); System.out.println(结果1:+ bd1.toString()); System.out.println(结果2:+ bd2.toString()); 结果1:13.300000000000000710542735760100185871124267578125 结果2:13.3是有什么情况需要结果1吗?我知道Java 1.5改变了 toString()方法,但这是预期的后果吗?
我也意识到 BigDecimal 有 doubleValue()等,但我正在使用的库有助于使用 toString(),我无法改变: - (
干杯。
解决方案嗯, API 确实解决了构造函数 BigDecimal(double val)中明显的不一致性:
此构造函数的结果可能有些不可预测。可能假设在Java中编写新的 BigDecimal(0.1)会创建一个 BigDecimal,它恰好等于 0.1(未缩放值为1,缩放为1) ,但它实际上等于到 0.1000000000000000055511151231257827021181583404541015625。这是因为0.1 不能是完全表示为双(o r,就此而言,作为任何有限长度的二进制分数)。因此,传递给构造函数的值并不完全等于 0.1,尽管有外观。
当必须将double用作BigDecimal 的源时,请注意此构造函数提供精确的转换;使用 Double.toString(double)方法将$ double转换为字符串并使用然后使用BigDecimal(String)$ b $时,它不会给出相同的结果b构造函数。要获得该结果,使用静态valueOf(double)方法。
故事的道德:痛苦似乎是自己造成的,只需使用 new BigDecimal(String val) 或 BigDecimal.valueOf(double val) 而不是=)
How is it that Java's BigDecimal can be this painful?
Double d = 13.3D; BigDecimal bd1 = new BigDecimal(d); BigDecimal bd2 = new BigDecimal(String.valueOf(d)); System.out.println("RESULT 1: "+bd1.toString()); System.out.println("RESULT 2: "+bd2.toString()); RESULT 1: 13.300000000000000710542735760100185871124267578125 RESULT 2: 13.3Is there any situation where Result 1 would be desired? I know that Java 1.5 changed the toString() method but was this the intended consequence?
Also I realise that BigDecimal has doubleValue() etc, but the library that I am working with helpfully uses a toString() and I can't change that :-(
Cheers.
解决方案Well, the API does address this apparent inconsistency in the constructor BigDecimal(double val):
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.
Moral of the story: The pain seems self-inflicted, just use new BigDecimal(String val) or BigDecimal.valueOf(double val) instead =)
更多推荐
“new BigDecimal(13.3D)”导致不精确的“13.3000000000000007105 ..”?
发布评论