1

这是我的代码的一部分:

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) )

然后我需要将它们更改为笛卡尔坐标。(这里出现一个小错误!)

然后我想计算两点之间的角度。

解析解不同于计算机解(因为误差很小)。我想让这两个解决方案相同。

4

1 回答 1

2

您是否试图防止分支?当我做这样的事情时,我通常会做一个小帮手:

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查找表,并在每一端放置一个额外的值来处理由错误引起的溢出。

[编辑] 我刚刚玩了一个没有分支的 [-1,1] 夹子。当然,这只能解决不准确的问题。如果你用一个完全超出范围的数字来调用它,它会爆炸:

inline double safer_acos (double val)
{
    double vals[] = {-1.0, val, val, 1.0};
    return acos( vals[int(2.0 + val)] );
}
于 2013-06-20T02:01:29.367 回答