0

The program gets 4 points(their coords) that form a convex figure and should give me the angle A2+angle A4 - 180 degrees. For the example :

1 3
0 2
1 1
2 2

I get uA2=90 and uA4=90, but when I do uA2+uA4-180 I get 2.0568e-007, instead of 0. But when I do just uA2+uA4 I get 180. I am sorry if a similar question was asked, but I didn't know how to search for it. Can anyone tell me why it happens and how can I repair it to show the right answer? Tho code:

#include <iostream>
#include <fstream>
#include <cmath>

#define PI 3.14159265

using namespace std;

ifstream f("date.in");

struct punct
{
    double x,y;
}A1,A2,A3,A4;

int main()
{
    double uA2,uA4;
    f>>A1.x>>A1.y>>A2.x>>A2.y>>A3.x>>A3.y>>A4.x>>A4.y;
//calculate cos of both angles
    uA2=((A1.x-A2.x)*(A3.x-A2.x)+(A1.y-A2.y)*(A3.y-A2.y))/
            (sqrt((A1.x-A2.x)*(A1.x-A2.x)+(A1.y-A2.y)*(A1.y-A2.y))*sqrt((A3.x-A2.x)*(A3.x-A2.x)+(A3.y-A2.y)*(A3.y-A2.y)));
    uA4=((A1.x-A4.x)*(A3.x-A4.x)+(A1.y-A4.y)*(A3.y-A4.y))/
            (sqrt((A1.x-A4.x)*(A1.x-A4.x)+(A1.y-A4.y)*(A1.y-A4.y))*sqrt((A3.x-A4.x)*(A3.x-A4.x)+(A3.y-A4.y)*(A3.y-A4.y)));
//calculate angles
    uA2=acos(uA2)*180.0/PI;
    uA4=acos(uA4)*180.0/PI;
//the part that gives me an incorrect answer
    cout<<uA2+uA4-180<<endl;
}
John Smith
  • 11
  • 1
  • 1
  • 4
  • 4
    Possible duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Wai Ha Lee Dec 02 '17 at 23:01
  • I had also this problem by calculating `sin(2*PI)` which returns also this value instead of 0. So I assumed these functions are not so precise ? – Julien Vernay Dec 02 '17 at 23:03
  • Floating point math is an approximation. That's the simple reason -- to read about it more, go to the link specified or do a google search on the topic. – PaulMcKenzie Dec 02 '17 at 23:04
  • and there is now way I could fix this in a simple way? I need to verify if uA2+uA4==180 or <180 or >180 for other things, and I have no idea how to do it if I get an error this way – John Smith Dec 02 '17 at 23:07
  • Use a tolerance - e.g. to check to see if a value is 180, check that it's in the range (for instance) 180-1e-5 and 180+1e-5. – Wai Ha Lee Dec 02 '17 at 23:20
  • @JohnSmith *and there is now way I could fix this in a simple way?* -- What is there to "fix"? That's how floating point math works on a binary computing machine. If you want exact calculations, don't use floating point. Otherwise, use a tolerance level where if the value is "close", it's considered equal. – PaulMcKenzie Dec 02 '17 at 23:24

1 Answers1

1

For floating point computation, we can use some very small offset value for marginal error, for example 1e-6.

    double diff = uA2 + uA4 - 180, threshold = 1e-6;
    if (diff < threshold && diff > -threshold) cout << "0" << endl;
    else cout << diff << endl;
   // cout<<uA2+uA4-180<<endl;
abdullah
  • 662
  • 5
  • 7