Arredondamento FORTRAN correspondente em C#
-
05-07-2019 - |
Pergunta
FORTRAN fornece diversas funções para converter um número de precisão dupla em um valor integral.O método usado para truncamento/arredondamento é diferente.Estou convertendo algoritmos científicos complexos que os utilizam.
De acordo com a documentação FORTRAN:
não é (x) retorna o valor integral entre x e 0, o x mais próximo.
não (x) Retorna o valor integral mais próximo a X, exceto que os casos de meio caminho são arredondados para o valor integral maior em magnitude.
zero (x) Converte x em um arredondamento de formato int para o valor INT mais próximo, exceto que os casos intermediários são arredondados para o valor int maior em magnitude.
Alguém tem uma implementação disso em C#?Pode ser complicado acertar.
(int)x parece corresponder aint()
Convert.ToInt32(x) não corresponde a nenhuma das opções acima.
Trunc(x) não corresponde a nenhuma das opções acima.
Round(x) pode corresponder a anint ou nint.
A diferença entre anint e nint parece ser o tipo de retorno, onde anint retorna um valor de precisão dupla, mas nint retorna um número inteiro.Ambos são usados (amostra real):
PRECISÃO DUPLA A, B, C, D, E, F, G
...valores definidos aqui...
F = ANINT(AB) + ANINT(C-D) + ANINT(B+D-E)
G = NINT(F) + 1D0;
Talvez um especialista em FORTRAN possa ajudar a esclarecer por que o autor optou por usar ambos (presumo que tenha sido intencional).
Solução
Das suas definições das chamadas, nint
e anint
são fornecidos por Math.Round
usando MidpointRounding.AwayFromZero
.
Para aint
, uma conversão explícita de double
para int
alcançará esse resultado.
Outras dicas
Pelo que posso ver, aint()
é apenas Math.Floor()
.
Para os outros dois, acho que você está certo ao dizer que a única diferença é o tipo de retorno: nint()
retorna um número inteiro real, enquanto anint()
retorna um duplo (fortran:real) que tem um valor integral.
Tenho uma implementação da função anint, segue o código:
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;
}