Вот часть моего кода:
double tmp = OP.innerProduct(OQ);
double tmp2 = -1;
и значение tmp
а также tmp2
это: (в двоичном виде)
tmp = 0b1011111111110000000000000000000000000000000000000000000000000001
tmp2= 0b1011111111110000000000000000000000000000000000000000000000000000
Если бы я использовал acos(tmp)
, он вернется nan
,
Я не хочу nan
значение, и я хотел бы игнорировать небольшую ошибку, чтобы сохранить tmp
в диапазоне [-1,1].
Как это сделать?
РЕДАКТИРОВАТЬ:
У меня есть две точки в сферической координате. (например, (r, 45,45) (r, 225, -45))
Затем мне нужно изменить их на декартову координату. (небольшая ошибка происходит здесь!)
Затем я хочу вычислить угол между двумя точками.
Аналитическое решение отличается от компьютерного решения (так как небольшая ошибка).
Я хотел бы сделать два решения одинаковыми.
Вы пытаетесь предотвратить ветвление? Обычно я делаю маленького помощника, когда делаю что-то вроде этого:
template<typename T>
inline T Clamp( T val, T low, T high ) {
return val < low ? low : (val > high ? high : val);
}
А потом:
double result = acos( Clamp(tmp, -1.0, 1.0) );
Если вы пытаетесь написать высоко оптимизированный код без ветвления, это не поможет. В зависимости от требуемой точности, вы можете рассмотреть возможность создания acos
посмотрите таблицу и просто добавьте дополнительное значение на каждом конце, чтобы обработать вызванное ошибками переполнение.
inline double safer_acos (double val)
{
double vals[] = {-1.0, val, val, 1.0};
return acos( vals[int(2.0 + val)] );
}
Других решений пока нет …