user2261693
user2261693

Reputation: 405

How to let -1==-1.0000000000001

Here is a part of my code:

double tmp = OP.innerProduct(OQ);
double tmp2 = -1;

and the value of tmp and tmp2 is: (in binary)

tmp = 0b1011111111110000000000000000000000000000000000000000000000000001
tmp2= 0b1011111111110000000000000000000000000000000000000000000000000000

If I used acos(tmp), it will return nan.

I don't want the nan value, and I would like to ignore the small error to keep tmp in the range [-1,1].

How to do so?

EDIT:

I have two points given in spherical coordinate. ( for example, (r,45,45) (r,225,-45) )

Then I need to change them to cartesian coordinate. (a small error occur here!)

Then I want to compute the angle between two points.

The analytical solution is different to computer solution(since the small error). I would like to make the two solutions same.

Upvotes: 1

Views: 266

Answers (1)

paddy
paddy

Reputation: 63471

Are you trying to prevent branching? I usually make a little helper when I'm doing anything like this:

template<typename T>
inline T Clamp( T val, T low, T high ) {
    return val < low ? low : (val > high ? high : val);
}

And then:

double result = acos( Clamp(tmp, -1.0, 1.0) );

If you're trying to write highly optimized code without branching, this won't help. Depending on the accuracy you require, you might consider making an acos lookup table and just put an extra value at each end to handle error-induced overflow.

[edit] I've just had a play around with a [-1,1] clamp without branching. Of course, this only cures inaccuracies. If you call it with a number that is grossly outside the range, it will bomb:

inline double safer_acos (double val)
{
    double vals[] = {-1.0, val, val, 1.0};
    return acos( vals[int(2.0 + val)] );
}

Upvotes: 2

Related Questions