【问题标题】:Subtracting bigDecimal numbers produces a precision of 0?减去 bigDecimal 数字会产生 0 的精度?
【发布时间】:2019-04-14 22:44:24
【问题描述】:

我正在减去两个 bigDecimal 数字。进入减法方法,它们都具有非零精度,但结果精度= 0。

据我所知,精度为 0 的 bigDecimal 数是不可能的。即使 0 也有 1 的精度。

精度是未缩放值的位数。例如,对于数字 123.45,返回的精度为 5。

(另见BigDecimal, precision and scale)。

相关区域:

BigDecimal test = (centerHP.getReal().subtract(inverseScale));

centerHP.getReal() 返回从该行创建的 bigDecimal

new BigDecimal(Double.toString(center.getReal()))

对于上下文center.real = -0.79,它是一个double。

原来如此

new BigDecimal("-0.79")

inverseScale 只是 1

double scale = 1;

BigDecimal inverseScale = (BigDecimal.ONE.divide(new BigDecimal(Double.toString(scale))));

我希望 test 是一个值为 -1.79 的 bigDecimal,int 表示应该是 -179,精度为 3,小数位数为 2。但是,紧随 BigDecimal 中的减法方法中的加法运算类,我的价值观如下:

并且测试等于:

请注意,所有其他值都是正确的,只是精度似乎是错误的。

【问题讨论】:

  • 您是否尝试在有问题的对象上调用precision() 方法?我认为调试器中显示的私有字段的值没有任何保证。

标签: java bigdecimal


【解决方案1】:

从该字段的 javadoc 中,0 表示精度未知。

/**
 * The number of decimal digits in this BigDecimal, or 0 if the
 * number of digits are not known (lookaside information).  If
 * nonzero, the value is guaranteed correct.  Use the precision()
 * method to obtain and set the value if it might be 0.  This
 * field is mutable until set nonzero.
 *
 * @since  1.5
 */
private transient int precision;

precision() 方法懒惰地确定精度。

public int precision() {
    int result = precision;
    if (result == 0) {
        long s = intCompact;
        if (s != INFLATED)
            result = longDigitLength(s);
        else
            result = bigDigitLength(inflate());
        precision = result;
    }
    return result;
}

【讨论】:

  • 这似乎已经解决了问题,在运行test.precision();之后,测试的精度设置为3。仍然很好奇为什么精度未知。
  • @TheChosenHero:确定精度需要时间。所以这仅在请求时完成,而不是在创建 BigDecimal 时完成。在被请求之前,内部数据成员被设置为 0 表示:仍然未知。只有查询精度后,才确定值并存储在内部成员中。
  • @TheChosenHero 任何延迟执行的操作都是为了节省计算。可能永远不需要此字段,因此不提前计算可以节省时间。顺便说一句,String.hashCode() 做同样的事情,只是按需计算(在设置之前它的默认值为 0,这意味着字符串散列的 hashCode 为 0,每次都会重新计算)
  • @PeterLawrey Lawrey 好吧,某些计算可能不需要精度。我将不得不更多地使用 BigDecimal 类并了解如何最好地使用它。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2021-09-27
  • 2014-12-15
  • 2016-05-14
  • 1970-01-01
  • 2021-02-01
  • 2016-06-14
  • 1970-01-01
  • 2013-03-05
相关资源
最近更新 更多