在Java应用程序中,我有一个包含以下情况的单元测试:
BigDecimal rendimentoLordoProvvisiorioExpected = new BigDecimal(2.85000);
BigDecimal rendimentoLordoProvvisiorioDB = null;
rendimentoLordoProvvisiorioDB = pucManager.getRendimentoLordoProvvisorio(date);
assertTrue(rendimentoLordoProvvisiorioExpected.compareTo(rendimentoLordoProvvisiorioDB) == 0);
将rendimentoLordoProvvisiorioExpected变量的值手动设置为2.85000,得到的值rendimentoLordoProvvisiorioDB为2.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