Я переводил .NET-код в Java и сталкивался с проблемой точности, не соответствующей.Средняя точка округления от нуля .net C# Decimal к Java Double
код .NET:
private decimal roundToPrecision(decimal number, decimal roundPrecision)
{
if (roundPrecision == 0)
return number;
decimal numberDecimalMultiplier = Math.Round(number/roundPrecision, MidpointRounding.AwayFromZero);
return numberDecimalMultiplier * roundPrecision;
}
Вызов roundToPrecision(8.7250, 0.05);
функции в коде выше, дает мне 8.75
, который, как ожидается.
Преобразование/перевод функции на Java выглядит следующим образом. Я не могу найти точный вариант
Math.Round
.
код Java:
public double roundToPrecision(double number, double roundPrecision) {
if (roundPrecision == 0)
return number;
int len = Double.toString(roundPrecision).split("\\.")[1].length();
double divisor = 0d;
switch (len) {
case 1:
divisor = 10d;
break;
case 2:
divisor = 100d;
break;
case 3:
divisor = 1000d;
break;
case 4:
divisor = 10000d;
break;
}
double numberDecimalMultiplier = Math.round(number/roundPrecision);
double res = numberDecimalMultiplier * roundPrecision;
return Math.round(res * divisor)/divisor;
}
Вызов roundToPrecision(8.7250, 0.05);
в коде Java дает мне 8.7
и это не правильно.
Я даже пробовал модифицировать код с BigDecimal
следующим образом на Java, используя ссылку здесь C# Double Rounding, но не повезло.
public double roundToPrecision(double number, double roundPrecision) {
if (roundPrecision == 0)
return number;
int len = Double.toString(roundPrecision).split("\\.")[1].length();
double divisor = 0d;
switch (len) {
case 1:
divisor = 10d;
break;
case 2:
divisor = 100d;
break;
case 3:
divisor = 1000d;
break;
case 4:
divisor = 10000d;
break;
}
BigDecimal b = new BigDecimal(number/roundPrecision);
b = b.setScale(len,BigDecimal.ROUND_UP);
double numberDecimalMultiplier = Math.round(b.doubleValue());
double res = numberDecimalMultiplier * roundPrecision;
return Math.round(res * divisor)/divisor;
}
Просьба указать, что мне нужно сделать, чтобы исправить это.
Вот несколько сценариев, чтобы опробовать.
- номер =
10.05
; точность =.1
; Ожидаемый =10.1
; - номер =
10.12
; точность =.01
; Ожидаемый =10.12
; - номер =
8.7250
; точность =0.05
; Ожидаемый =8.75
; - номер =
10.999
; точность =2
; Ожидаемый =10
; - номер =
6.174999999999999
; точность =0.05
; Ожидаемый =6.20
;
Примечание: У меня более 60 тысяч чисел и точность может варьироваться от 1 десятичной до 4 знаков после запятой. Результат .NET должен точно соответствовать Java.
Благодарим за ответ. Однако я уже пробовал это. Попробуйте senarios 1 и 2 (я обновил вопрос). Они не дают ожидаемого результата в вашей реализации. –
Ваше решение бросает 'java.lang.ArithmeticException: Неограничивающее десятичное расширение; нет точного представимого десятичного результата' на 'BigDecimal numberDecimalMultiplier = number.divide (roundPrecision) .setScale (0, RoundingMode.CEILING);' когда число равно 10.0, а точность 0,1 –
Каковы ваши аргументы, когда он выдает исключение? – gunnerone