使用Math.Ceil(Java)浮点精度

时间:2015-02-10 09:44:26

标签: java floating-point

我正在实施业务规则来计算库存水平的百分比增长:

Stock level | Percentage Increase | Expected output
    100     |           93        |        193

由于十进制库存水平未明确定义,因此规则是对输出进行舍入:

public int calculateStockLevel(int rawStockLevel, double percentageIncrease) {
    return Math.ceil(rawStockLevel * (1 + (percentageIncrease / 100));
}

上述情况的实际输出:194(测试失败)

这看起来像一个浮点精度误差,是一个优雅的&让这个测试通过的可读方式?

2 个答案:

答案 0 :(得分:2)

你应该使用BigDecimal来指定你想要的精度,但对于你的情况你可以做一些更简单的事情:最后除以100。

public int calculateStockLevel(int rawStockLevel, double percentageIncrease) {
    return Math.ceil(rawStockLevel * (100 + percentageIncrease) / 100);
}

答案 1 :(得分:0)

二进制浮点类型不能表示十进制中的每个值。因此percentageIncrease / 100将获得二进制中最接近的表示。在您的情况下,双精度的精确值0.93是0.930000000000000048849813083507,它略大于真正的十进制值。因此,在ceil之后,它将被舍入到0.94

如果您想要精确的十进制输出,则必须使用十进制算术,例如BigDecimal。但在你的情况下你可以用普通整数来做,利用ract,如果除法的余数不为零,结果的小数部分必须大于0。

int temp   = rawStockLevel * (100 + percentageIncrease);
int result = temp/100;
if (temp % 100 != 0)
    result++; // round up if not divisible by 100
return result;