使用点积结果时,为什么acos()导致“ nan(ind)”?

时间:2018-09-02 14:54:40

标签: c++ armadillo math.h

我对这个问题非常困惑。我正在运行的代码是:

double dotProduct = dot(A, B);
std::cout << dotProduct << std::endl;
theta = acos(dotProduct);
std::cout << theta << std::endl;

其输出为

-1
ANGLE: -nan(ind)

但是,以下工作原理:

double dotProduct = dot(A, B);
std::cout << dotProduct << std::endl;
dotProduct = -1;
theta = acos(dotProduct);

提供输出:

-1
ANGLE: 3.14159

此外,如果我将dotProduct强制转换为浮点数,则acos()会正确输出角度:

double dotProduct = dot(A, B);
std::cout << dotProduct << std::endl;
theta = acos((float) dotProduct);

也导致输出

-1
ANGLE: 3.14159

对于dot()函数,我正在使用Armadillo库。我不明白的是为什么当我设置dotProduct = -1时acos()应该工作,但是当dot()函数输出它时却不能工作。我在做什么错了?

1 个答案:

答案 0 :(得分:2)

我假设AB是归一化向量,因此您希望dot(A, B)-11之间。对于浮点数学,这不一定是正确的。 |dot(A, B)|可以比1稍大。我敢打赌,如果您以更高的精度打印它,您会发现您的值比-1略小。

因此,您需要将dot(A, B)-1夹在1之间。甚至更好的是,如果输入介于acos()-1之间,则仅调用1

double safe_acos(double value) {
    if (value<=-1.0) {
        return <pi>;
    } else if (value>=1.0) {
        return 0;
    } else {
        return acos(value);
    }
}

这可能会稍快一些,因为避免调用acos()来获取越界值。

注意:如果您进行3D数学运算,则极有可能避免完全调用acos()。使用三角恒等式,通常我们可以用更快,更准确的解决方案代替它。