Я столкнулся с проблемой числовой точности в Си с методами tan / atan.Я предполагаю, что здесь что-то отсутствует, но я не знаю, что.
Я приложил нижеприведенный код, который пытается вычислить некоторые углы (a
и b
) из ряда чисел(m6
, m7
и m8
), которые являются тригонометрическими функциями, применяемыми к этим углам (как показано в комментариях к коду), затем я инвертирую эти углы для восстановления m6
, m7
и m8
и сравнивая их с исходными числами, которые я ожидал сопоставить с 14-й или 15-й цифрой, поскольку я использую double
числа.Однако, как вы можете видеть из результатов, есть некоторые числовые различия, которые я не могу объяснить для случаев atan
.Кто-нибудь знает, что происходит?
a - atan() - -0.0003351970075579
a - atan2() - -0.0003351970075579
b - asin() - 0.0000856336001047
m6 - got [ -0.0000856336000000 ]
m6 - expected [ -0.0000856336000000 ]
m7 - got [ -0.0003351970000519 ]
m7 - expected [ -0.0003351970000000 ]
m8 - got [ 0.9999999401549271 ]
m8 - expected [ 0.9999999400000000 ]
Вы можете выполнить код по этой ссылке с кодовой панели: http://codepad.org/lzMMcgnb
#include <stdio.h>
#include <math.h>
int main()
{
/* m6 = -sin b*/
double m6 = -0.0000856336;
/* m7 = sin a * cos b */
double m7 = -0.0003351970000000;
/* m8 = cos a * cos b */
double m8 = 0.9999999400000000;
/* a = atan(m7 / m8) = atan2(m7,m8)*/
double a1 = atan(m7 / m8);
double a2 = atan2(m7 , m8);
double b = -asin(m6);
printf("a - atan() - %.16f\n", a1);
printf("a - atan2() - %.16f\n", a2);
printf("b - asin() - %.16f\n", b);
/* Inverse transformation */
double m6p = -sin(b);
double m7p = sin(a2) * cos(b);
double m8p = cos(a2) * cos(b);
printf("m6 - got [ %.16f ]\n", m6p);
printf("m6 - expected [ %.16f ]\n\n", m6);
printf("m7 - got [ %.16f ]\n", m7p);
printf("m7 - expected [ %.16f ]\n\n", m7);
printf("m8 - got [ %.16f ]\n", m8p);
printf("m8 - expected [ %.16f ]\n", m8);
return 1;
}