为什么这两个BigDecimal之间的比较失败



在Java应用程序中,我有一个包含以下情况的单元测试:

BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal(2.85000);
BigDecimal rendimentoLordoProvvisiorioDB = null;
rendimentoLordoProvvisiorioDB = pucManager.getRendimentoLordoProvvisorio(date);
assertTrue(rendimentoLordoProvvisiorioExpected.compareTo(rendimentoLordoProvvisiorioDB) == 0);

rendimentoLordoProvvisiorioExpected变量的值手动设置为2.85000,得到的值rendimentoLordoProvvisiorioDB2.85000

问题是,当我把这个比较到assertTrue() JUnit函数

assertTrue(rendimentoLordoProvvisiorioExpected.compareTo(rendimentoLordoProvvisiorioDB) == 0);

它失败,因为rendimentoLordoProvvisiorioExpected似乎是2.850000000000000088817841970012523233890533447265625而不是2.85000(如设置)。

为什么?如何修改前面的代码,将rendimentoLordoProvvisiorioExpected设置为期望值2.85000?

BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal("2.85000");代替BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal(2.85000);您所做的是从double类型构建一个BigDecimal,而double类型是不精确的。

因为您使用一个浮点值初始化BigDecimal,通过使用double类型调用构造函数。双精度数是浮点数。使用字符串:

BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal("2.85000");

你应该阅读BigDecimal关于调用double版本的构造函数的文档。

使用BigDecimal时,是将以2为基数的浮点数转换为以10为基数的浮点数。数字2.85没有完美的以二进制为基础的浮点数表示,最好的近似值似乎接近于:

>>> decimal.Decimal(2.85)
Decimal('2.850000000000000088817841970012523233890533447265625')

你应该阅读更多关于浮点数的知识,例如:What Every Programmer should Know about floating - point Arithmetic

最新更新