[英]Java BigDecimal.doubleValue between Java 6 and Java 8
[英]How accurate is BigDecimal.doubleValue() if no operation is applied on the amount
我需要发送一个' 双倍 '的值,但我是:
现在我知道当你对它们应用算术运算时, double值会失去精度, 但是如果我尝试基于BigDecimal发送double值, 我可能会得到什么 ,例如(我相信)上面的场景是。
这很重要,因为我必须以这种方式通过SOAP发送货币价值 - 别无他法。
我还有使用String作为BigDecimal创建的场景,然后在其上调用doubleValue() 。 在这种情况下我能得到什么?
编辑:示例代码:
long amountInCents = 1852;
BigDecimal amountInWholeUnits = BigDecimal.valueOf(amountInCents).scaleByPowerOfTen(-2);
double amountToSend = amountInWholeUnits.doubleValue();
至于金额是以字符串形式提供的情况:
double amountToSend = new BigDecimal("18.52").doubleValue();
现在我有示例代码,我只是认为我可以测试并看到,所以我做了一个for循环并使用了System.out.println :到目前为止很好,值是正确的,所以我相信这将是相同的发送通过SOAP。 如果我错了,请纠正我。
由于1美分等于1/100美元,并且由于数字1/100或0.01
不能完全表示为二进制浮点数,因此会出现一些轻微的精度损失。 在$ 18.52的特定示例中,结果double
将最接近的double
值保持为18.52,但它不会完全等于18.52。
Java双打本质上是近似值。 换句话说, 不能保证存在与任何给定浮点值完全对应的double值 。
BigDecimal通过精确表示浮点值来工作。 但这意味着对于BigDecimal的任何有效值,不能保证存在表示它的double值。 无论你如何创建BigDecimal,都是如此。
如果您需要金额的精确表示,则不能使用双精度表示。 您需要在所有计算过程中继续使用BigDecimal,或者找到符合您需求的整数表示。 经常使用整数的分数,但请记住,计算有时可能涉及分数的一小部分,如果计算多次完成,舍入策略可能会产生很大的影响。
如果你没有计算要做,那么使用一个整数(例如整数仙数)来表示该值就没问题了。
BigDecimal
的OpenJDK实现似乎达到了double
的自然准确性。
BigDecimal.valueOf(1852).scaleByPowerOfTen(-2);
创建一个BigDecimal,其值为(有效) 1852
, scale
为-2
。
amountInWholeUnits.doubleValue();
检查比例,如果它不是0(就像在这种情况下),它会:
Double.parseDouble(this.toString());
所以基本上你计划的操作的结果将是double
,接近18.52
, double
。
显然,这也假设所有JDK都做类似的事情(可能不是这种情况)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.