【问题标题】:BigDecimal and Double digit limit?BigDecimal 和两位数限制?
【发布时间】:2017-12-03 23:44:09
【问题描述】:

我正在制作一个 phi(黄金比例)计算器,但我得到的答案的精度存在问题。 我意识到我的答案似乎有一个固定数量的数字,然后它就被截断了。起初我认为这是双打的问题,所以我改用 BigDecimals。然而问题仍然存在。

这是我原来的双重逻辑:

public static final double PHI = 1.6180339887498948482045;

b = Double.parseDouble(field.getText());
a = b * PHI;
aPlusB = a + b;

System.out.println(a.toString());

这是我的 BigDecimal Logic 的代码:

public static final double PHI = 1.6180339887498948482045;

BigDecimal phi = new BigDecimal(calculationHolder.PHI);
MathContext context = new MathContext(15, RoundingMode.HALF_UP);

BigDecimal a = new BigDecimal(BigInteger.ZERO);         
BigDecimal b = new BigDecimal(BigInteger.ZERO);            
BigDecimal aPlusB = new BigDecimal(BigInteger.ZERO);

b = new BigDecimal(field.getText());
a = b.multiply(phi, context);
aPlusB = a.add(b, context);

System.out.println(a.toString());

现在如果我让 b = 1:

我的双重逻辑将返回 1.618033988749895(比实际值少很多位数)。

如果我使用我的 BigDecimal 逻辑,它将返回 1.61803398874989(甚至更不精确)

如果我要为 b 使用一个非常大的数字,例如 123456789123456,

我的双精度逻辑将返回 199757280943680.16,而 BigDecimal 逻辑将返回 199757280943680(更不精确,甚至没有任何小数)。

我对这种行为感到困惑。看起来,如果有的话,BigDecimal 逻辑给我的答案更不准确,我不知道为什么。

有人能解释一下吗?

【问题讨论】:

    标签: java string floating-point precision bigdecimal


    【解决方案1】:

    您在此处指定了 15 位小数的精度:

    new MathContext(15, RoundingMode.HALF_UP);
    

    你在这里得到了 15 位小数的精度:

    1.61803398874989
    

    你得到了你想要的。你了解first constructor parameter 的作用吗?

    【讨论】:

    • 不是小数点后 14 位吗?还是从小数点开始计数?即使是这种情况,为什么 BigDecimal 会停止提供更大数量的输入的精度?
    • 或者文档中的十进制数字是指一般数字吗?我的印象是它们的意思是小数位。我的错,我会测试一下。
    • @MainManAndy:您或许应该阅读更多关于 scale (小数点 places 的数量)之间的区别 -- 更多或小于小数点右侧的位数)和精度(总位数 - 小数位数,因为 BigDecimal 不支持任何0..9 以外的其他数字)。
    • @MainManAndy: 199757280943680 也是 15 位数字。你指定你不想要超过 15 位数字,所以这就是你得到的。
    • 表示“有效数字”,即所有个数字。它与“小数位”不同。
    猜你喜欢
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 1970-01-01
    • 2023-01-08
    • 1970-01-01
    • 2021-03-13
    相关资源
    最近更新 更多