BigDecimal compareTo不按预期工作 [英] BigDecimal compareTo not working as expected

查看:102
本文介绍了BigDecimal compareTo不按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 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:



  1. 这个构造函数的结果可能有点不可预知的。有人可能会认为在Java中编写 new BigDecimal(0.1)会创建一个 BigDecimal ,它正好等于0.1(未缩放值为1,范围为1),但实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1不能完全表示为 double (或者,就此而言,作为任何有限长度的二进制分数)。因此,传递给构造函数的值并不完全等于0.1,尽管有外观。

  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.

String 构造函数是完全可预测的:写 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屋!

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