Java BigDecimal Compare未按预期工作

Java BigDecimal Compare未按预期工作,java,bigdecimal,Java,Bigdecimal,根据forBigDecimal,compareTo函数不考虑比较期间的刻度 现在我有了一个类似这样的测试用例: BigDecimal result = callSomeService(foo); assertTrue(result.compareTo(new BigDecimal(0.7)) == 0); //this does not work assertTrue(result.equals(new BigDecimal(0.7).setScale(10, BigDecimal.ROUND_

根据for
BigDecimal
compareTo
函数不考虑比较期间的刻度

现在我有了一个类似这样的测试用例:

BigDecimal result = callSomeService(foo);
assertTrue(result.compareTo(new BigDecimal(0.7)) == 0); //this does not work
assertTrue(result.equals(new BigDecimal(0.7).setScale(10, BigDecimal.ROUND_HALF_UP))); //this works
我期望函数返回的值是
0.7
,并且具有10的刻度。打印该值会显示预期结果。但是
compareTo()
函数似乎没有按照我认为应该的方式工作

这是怎么回事?

新的BigDecimal(0.7)
不代表0.7

它表示0.699999999955591079014993733838305473732763671875(精确)

这是因为
double
literal
0.7
并不完全代表0.7

如果需要精确
BigDecimal
值,则必须使用
字符串
构造函数(实际上,所有不接受
双值的构造函数都可以工作)

请尝试使用新的BigDecimal(“0.7”)

报告中有一些相关说明:

  • 此构造函数的结果可能有些不可预测。有人可能会假设,在Java中编写
    新的BigDecimal(0.1)
    会创建一个
    BigDecimal
    ,它正好等于0.1(未标度的值1,标度为1),但实际上等于0.1000000000000005555115123125782702118158340451015625。这是因为0.1不能精确地表示为
    双精度
    (或者,就此而言,表示为任何有限长度的二进制分数)。因此,传递给构造函数的值并不完全等于0.1,尽管如此

  • 另一方面,
    字符串
    构造函数是完全可预测的:编写
    新的BigDecimal(“0.1”)
    会创建一个
    BigDecimal
    ,正如人们所期望的那样,它正好等于0.1。因此,一般建议优先使用此选项

  • 当必须将
    double
    用作
    BigDecimal
    的源时,请注意此构造函数提供了精确的转换;它不会给出与使用方法然后使用构造函数将
    双精度
    转换为
    字符串
    相同的结果。要获得该结果,请使用
    static
    方法


  • 总结一下:如果您想创建一个具有固定十进制值的
    BigDecimal
    ,请使用
    String
    构造函数。如果您已经有一个
    double
    值,那么将提供比使用更直观的行为。

    您希望该值为0.7,但您确定吗?您是否尝试过让callSomeService简单地返回新的BigDecimal(0.7)?@CPerkins是的,对此非常确定。我打印了结果,
    equals
    方法也在工作。不管怎样,问题解决了:)这个问题也让我困惑,直到我明白我是在用双精度来创建一个大十进制…:-\