“new BigDecimal(13.3D)”导致不精确的“13.3000000000000007105 ..”? [英] "new BigDecimal(13.3D)" results in imprecise "13.3000000000000007105.."?

查看:129
本文介绍了“new BigDecimal(13.3D)”导致不精确的“13.3000000000000007105 ..”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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)中明显的不一致性



  1. 此构造函数的结果可能有些不可预测。可能
    假设在Java中编写新的
    BigDecimal(0.1)会创建一个
    BigDecimal,它恰好等于
    0.1(未缩放值为1,缩放为1) ,但它实际上等于

    0.1000000000000000055511151231257827021181583404541015625。这是因为0.1 不能是
    完全表示为双
    (o r,
    就此而言,作为任何有限长度的二进制分数
    )。因此,传递给
    构造函数的
    值并不完全等于
    0.1,尽管有外观。


  2. <另一方面,字符串构造函数是完全可预测的:
    写入新的BigDecimal(0.1)会创建
    a BigDecimal,这正好等于
    0.1,正如人们所期望的那样。因此,通常建议在
    首选项中使用
    String构造函数。


  3. 当必须将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.3

Is 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):

  1. 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.

  2. 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.

  3. 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 ..”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆