Math.Ceil (Java) 的浮点精度
Floating point precision with Math.Ceil (Java)
我正在实施业务规则来计算库存水平的百分比增长:
Stock level | Percentage Increase | Expected output
100 | 93 | 193
由于小数库存水平未明确定义,规则是对输出进行四舍五入:
public int calculateStockLevel(int rawStockLevel, double percentageIncrease) {
return Math.ceil(rawStockLevel * (1 + (percentageIncrease / 100));
}
上述情况的实际输出:194
(测试失败)
这看起来像是一个浮点精度错误,请问有什么优雅且可读的方法可以让这个测试通过?
您应该使用 BigDecimal 来指定您想要的精度,但对于您的情况,您可以做一些更简单的事情:最后除以 100。
public int calculateStockLevel(int rawStockLevel, double percentageIncrease) {
return Math.ceil(rawStockLevel * (100 + percentageIncrease) / 100);
}
二进制浮点类型不能准确表示每个十进制值。所以 percentageIncrease / 100
将得到最接近的二进制表示。在您的情况下,双精度 0.93 的确切值为 0.930000000000000048849813083507,它比真正的十进制值略多。因此在 ceil
之后它会向上舍入到 0.94
如果你想要精确的十进制输出,你必须使用十进制算术,比如BigDecimal
。但在你的情况下,你可以用普通整数来做,利用如果除法的余数不为零,结果的小数部分必须大于 0 的事实。
int temp = rawStockLevel * (100 + percentageIncrease);
int result = temp/100;
if (temp % 100 != 0)
result++; // round up if not divisible by 100
return result;
我正在实施业务规则来计算库存水平的百分比增长:
Stock level | Percentage Increase | Expected output
100 | 93 | 193
由于小数库存水平未明确定义,规则是对输出进行四舍五入:
public int calculateStockLevel(int rawStockLevel, double percentageIncrease) {
return Math.ceil(rawStockLevel * (1 + (percentageIncrease / 100));
}
上述情况的实际输出:194
(测试失败)
这看起来像是一个浮点精度错误,请问有什么优雅且可读的方法可以让这个测试通过?
您应该使用 BigDecimal 来指定您想要的精度,但对于您的情况,您可以做一些更简单的事情:最后除以 100。
public int calculateStockLevel(int rawStockLevel, double percentageIncrease) {
return Math.ceil(rawStockLevel * (100 + percentageIncrease) / 100);
}
二进制浮点类型不能准确表示每个十进制值。所以 percentageIncrease / 100
将得到最接近的二进制表示。在您的情况下,双精度 0.93 的确切值为 0.930000000000000048849813083507,它比真正的十进制值略多。因此在 ceil
之后它会向上舍入到 0.94
如果你想要精确的十进制输出,你必须使用十进制算术,比如BigDecimal
。但在你的情况下,你可以用普通整数来做,利用如果除法的余数不为零,结果的小数部分必须大于 0 的事实。
int temp = rawStockLevel * (100 + percentageIncrease);
int result = temp/100;
if (temp % 100 != 0)
result++; // round up if not divisible by 100
return result;