C# - (Im)precisão de cálculos

C# - (Im)precisão de cálculos

Como em todas as linguagens, fazer cálculos é um compromisso entre rapidez e precisão.

Num programa em que estou a trabalhar, os cálculos das coordenadas finais de uma semi-recta, não dão certo com o que se obtém do Autocad. O Autocad é uma calculadora de referência para estas comprovações.



O erro que se verifica tem a ver com a questão de os números de ponto ou vírgula flutuante serem uma aproximação e não um resultado preciso. Ao usar estes números para operações, ainda por cima encadeadas, o erro propaga-se.

Na imagem seguinte, nas primeiras linhas, os ângulos calculados pelo programa para a inclinação de 5% (no print escreve-se 0.005 mas aí não deveria ter % à frente), tenho depois o valor calculado por uma calculadora. Verifica-se que o valor é igual/aproximado. 0.00499958 radianos mas ao detalhe já não são iguais.

O programa pega numa inclinação incial, e vai calculando as coordenadas finais com a elevação da inclinação da recta.
Na última linha podemos comparar o valor de calculadora 0.049958395 com o valor da iteracção 45 0.0499999433


Aqui a comprovação das coordenadas correctas, o azul deveria corresponder às coordenadas da interacção 45. Vemos que há uma diferença em X de 6 mm e em Y de vários centímetros.
A magenta seria a inclinação de 2.5% que deve corresponder à interacção 20



As coordenadas a amarelo são semelhantes em CAD e no cálculo, já que esta iteração não sofre de erro acumulado.

Como se resolver isto?
Seja qual for o caminho haverá sempre um erro. Para a maior parte dos casos o código que estou a usar seria suficiente, as variáveis são do tipo DOUBLE (vírgula flutuante). O Autocad, assim como outros programas de CAD e de Traçado não podem usar estes cálculos portanto a estratégia deverá passar pelo uso de variáveis tipo DECIMAL (para c#) ou outro tipo de estratégias como livrarias ou artifícios de cálculo.

Vou tentar adoptar o seguinte:
Em vez de acumular / somar o ângulo calculado em radianos sucessivamente, vou antes somar em % e depois calcular a coordenada correspondente a esse ângulo (em radianos internamente). Assim posso evitar alguma acumulação de erro...



Como curiosidade, como trabalho também em Linux, Ubuntu, ao portar o código para este sistema quis verificar se os resultados eram os mesmos, já que o processador é diferente assim como o Sistema Operativo e o motor de .Net é o Mono. Os resultados são iguais.


Comentários

Mensagens populares deste blogue

Python - Automatização em ISPOL

Linha do Oeste - Breve visita

AMV – Aparelhos de Mudança de Via