BigDecimal compareTo不按预期工作 [英] BigDecimal compareTo not working as expected
问题描述
根据 BigDecimal 的noreferrer> JavaDoc , compareTo
函数在比较期间不考虑比例。
According to the JavaDoc for BigDecimal
, the compareTo
function does not account for the scale during comparison.
现在我的测试用例看起来像这样:
Now I have a test case that looks something like this:
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()
函数似乎没有像我认为的那样工作。
The value I'm expecting the function to return is 0.7
and has a scale of 10. Printing the value shows me the expected result. But the compareTo()
function doesn't seem to be working the way I think it should.
发生了什么在这里?
推荐答案
新BigDecimal(0.7)
不代表0.7。
它代表0.6999999999999999555910790149937383830547332763671875(确切地说)。
It represents 0.6999999999999999555910790149937383830547332763671875 (exactly).
原因是 double
literal 0.7
并不完全代表0.7。
The reason for this is that the double
literal 0.7
doesn't represent 0.7 exactly.
如果您需要精确 BigDecimal
值,必须使用字符串
构造函数(实际上所有构造函数不接受 double
值将起作用)。
If you need precise BigDecimal
values, you must use the String
constructor (actually all constructors that don't take double
values will work).
尝试新的BigDecimal(0.7)
。
BigDecimal的JavaDoc(double )
constr uctor 有一些相关的注释:
The JavaDoc of the BigDecimal(double)
constructor has some related notes:
-
这个构造函数的结果可能有点不可预知的。有人可能会认为在Java中编写
new BigDecimal(0.1)
会创建一个BigDecimal
,它正好等于0.1(未缩放值为1,范围为1),但实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1不能完全表示为double
(或者,就此而言,作为任何有限长度的二进制分数)。因此,传递给构造函数的值并不完全等于0.1,尽管有外观。
The results of this constructor can be somewhat unpredictable. One might assume that writing
new BigDecimal(0.1)
in Java creates aBigDecimal
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 adouble
(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.
String 另一方面,code>构造函数是完全可预测的:写
new BigDecimal(0.1)
创建一个 BigDecimal
完全等于0.1,正如人们所期望的那样。因此,通常建议 字符串
构造函数优先于此使用。
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.
当 double
必须用作 BigDecimal
的源时,请注意此构造函数提供了精确的转换;它使用 double 转换为 String
的结果不一样/download.oracle.com/javase/6/docs/api/java/lang/Double.html#toString%28double%29rel =noreferrer> Double.toString(double)
方法然后使用 BigDecimal(String)
构造函数。要获得该结果,请使用 static
valueOf(double)
method。
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.
总结一下:如果你想创建一个带有固定小数的 BigDecimal
value,使用 String
构造函数。如果已经 double
值,那么 BigDecimal.valueOf(double)
将提供更直观的行为而不是使用 new BigDecimal(double)
。
So to summarize: If you want to create a BigDecimal
with a fixed decimal value, use the String
constructor. If you already have a double
value, then BigDecimal.valueOf(double)
will provide a more intuitive behaviour than using new BigDecimal(double)
.
这篇关于BigDecimal compareTo不按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!