Я использую бизнес-правило для расчета процентного прироста на уровне запасов:
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
. Но в вашем случае вы можете просто сделать это в виде простого целого числа, используя 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;
BigDecimal
; также есть Joda Money (о последнем, я знаю, что он существует, я никогда не использовал его на самом деле)