Java Double Trouble - 如何在不使用BigDecimal的情况下确保4.45是4.45?

时间:2014-10-17 17:18:41

标签: java double rounding truncate

所以:

//aValue = 4.45
//bValue = 4.35
//maxValueDiff = 0.1
//The absolute value of a - b = 0.1

if( Math.abs(aValue - bValue) <= maxValueDiff ) return true;
logger.info("valueDiffCheck a:" + aValue +" b:"+ bValue + " e1:" + maxValueDiff);

为什么我会在日志中看到这一点:

valueDiffCheck a:4.45 b:4.35 e1:0.1

怀疑这是因为Double是一种双重痛苦,但是如果不是这样的话,那么我不应该那么?喜欢它应该打印0.1实际上是0.10000000111或什么? ......或者是否有关于打印格式的麻烦?

目标代码是高性能的,有很多数据,所以我们不想使用BigDecimal。确保0.44为0.44的最佳选择是什么?

好吧,让我明确指出我们只需要两位小数。使用BigDecimal所涉及的准确性是主要的过度杀伤力。

3 个答案:

答案 0 :(得分:3)

我通过在可能出现的地方使用错误边距来解决此问题。以下是一种非常简单的方法 - 但不一定是最好的方式(您可能希望它更集中,可配置等) - 修改您的代码来执行此操作:

private static final double ERROR = 1e-7;

// SNIP

if( Math.abs(aValue - bValue) <= maxValueDiff + ERROR) return true;
logger.info("valueDiffCheck a:" + aValue +" b:"+ bValue + " e1:" + maxValueDiff);

答案 1 :(得分:2)

如果你想要准确,我没有看到任何使用BigDecimal的方法。

但是,根据您对此数字的处理方式,您可以始终使用Math.round来围绕&#34;确保&#34;你有&#34;正确&#34;小数集。

Round a double to 2 decimal places

答案 2 :(得分:0)

您始终可以考虑使用自己的十进制类来使用long来存储值和小数占位符。

public Class MyDecimal
{
    private long value = 0;
    private long decimalPlace = 0;

    ...
}

这意味着你可以做0.44这样的事情:

MyDecimal decimal = new MyDecimal(44, 2);

正如其他答案所述,BigDecimal将是确保准确性的最佳选择。