Подходящее округление Фортрана в C #
-
05-07-2019 - |
Вопрос
FORTRAN предоставляет несколько функций для преобразования числа с двойной точностью в целое значение. Метод, используемый для усечения / округления, отличается. Я конвертирую сложные научные алгоритмы, которые их используют.
Согласно документации FORTRAN:
aint (x) возвращает целое значение между x и 0, ближайшим x.
anint (x) возвращает ближайшее целочисленное значение для x, за исключением случаев, когда наполовину
округляется до целочисленного значения, большего по величине.
nint (x) преобразует x в округление формата int до ближайшего значения int, кроме
полпути округляются до значения int, большего по величине.
У кого-нибудь есть реализация этого в C #? Это может быть сложно сделать это правильно.
(int) x соответствует aint ()
Convert.ToInt32 (x) не соответствует ни одному из перечисленных.
Trunc (x) не соответствует ни одному из вышеперечисленных.
Round (x) может соответствовать anint или nint.
Разница между anint и nint, по-видимому, в типе возврата, где anint возвращает значение двойной точности, а nint возвращает целое число. Используются оба (острый образец):
ДВОЙНАЯ ТОЧНОСТЬ A, B, C, D, E, F, G
... значения, установленные здесь ...
F = ANINT (A-B) + ANINT (C-D) + ANINT (B + D-E)
G = NINT (F) + 1D0;
Возможно, эксперт ФОРТРАН мог бы помочь уточнить, почему автор решил использовать оба (я предполагаю, что это было сделано намеренно).
Решение
Из ваших определений вызовов nint
и anint
предоставляются Math.Round
используя MidpointRounding.AwayFromZero
.
Для aint
явное приведение от double
к int
приведет к такому результату.
Другие советы
Из того, что я вижу, aint ()
- это просто Math.Floor ()
. Р>
Для двух других, я думаю, вы правы, единственное отличие состоит в типе возвращаемого значения: nint ()
возвращает действительное целое число, а anint ()
возвращает двойное (fortran: real), которое имеет целое значение.
У меня есть реализация функции anint, следуйте коду:
double anint(double x)
{
int a;
double y;
a = (int)x; //a=9
if (10 * x - 10 * (double)a >= 5)
{
a = a + 1;
}
y = (double)a;
return y;
}