This is a discussion on please help !! within the C Programming forums, part of the General Programming Boards category; Hello. This is a very simple program for calculating some parameters of a triangle and at first it seems to ...

Hello. This is a very simple program for calculating some parameters of a triangle and at first it seems to be working fine. The problem is though, I do get wrong output for some tricky values. So for example if the input is a=1.3847, b=0.2497 and c=1.362 the output tells me it is an acute triangle which is not true. The program recognizes one of the cosine values to be 0 but still doesn't tell me it is a right triangle ... Any idea what am I missing ??

Much appreciated!

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define M_PI 3.14159265358979323846

int main(int argc, char** argv) {

double a,b,c;

printf("Enter side lengths a, b and c:\n");

if(scanf("%lf%lf%lf",&a,&b,&c)!=3||a<=0||b<=0||c<=0)
{
printf("\nInvalid input.\n");
printf("You may not enter non-numeric and 0 or negative values.\n");
return 0;
}
else
{
/* measurement of the angles in radians and degrees */
double cos_A=(b*b+c*c-a*a)/(2*b*c);
double cos_B=(a*a+c*c-b*b)/(2*a*c);
double cos_C=(a*a+b*b-c*c)/(2*a*b);
double pi=M_PI;
double deg_A=acos(cos_A)*(180/pi);
double deg_B=acos(cos_B)*(180/pi);
double deg_C=acos(cos_C)*(180/pi);

if (a+b>c&&a+c>b&&b+c>a)
{
if (a==b&&b==c)
{
printf("The triangle is equilateral.\n");
}
else if (a==b||a==c||b==c)
{
printf("The triangle is isosceles.\n");
}
else
{
printf("The triangle is scalene.\n");
}
if (cos_A==0||cos_B==0||cos_C==0)
{
printf("The triangle is a right triangle.\n");
}
else if (deg_A>90||deg_B>90||deg_C>90)
{
printf("The triangle is obtuse.\n");
}
else
{
printf("The triangle is acute.\n");
}
}
else
{
printf("The triangle does not exist.\n");
return 0;
}
}
return 0;
}```

2. Due to truncation effects, it is not a good idea to test two floating point numbers for equality. You should set a small tolerance, like this:

Code:
```if( a==b ) printf( "Yay!\n" ); /* WRONG */
if( a-b < EPSILON ) printf( "Woohoo!\n" ); /* BETTER */```
And the triangle you mentioned actually is acute; it's almost an isosceles triangle with two long sides and a short one so all its angles will be less than 90.

3. Floating point representation is inaccurate in computers. Print out the values of cos_A, cos_B and cos_C, to 20 or so decimal places, and see what you get (add these lines):
Code:
```printf("cos_A = %.20lf, cos_B = %.20lf, cos_C = %.20lf\n", cos_A, cos_B, cos_C);
printf("deg_A = %.20lf, deg_B = %.20lf, deg_C = %.20lf\n", deg_A, deg_B, deg_C);```

Also, you don't need the following line, just use M_PI in your equations.
Code:
`double pi=M_PI;`

4. Thank you for your replies. I actually guessed there would be something wrong with floating point numbers but I couldn't figure out the solution. The 'small tolerance' solution is great. Thanks again ...

5. Thanks for the reply. Actually the program was much longer and I was calculating the area and other stuff as well. Except for the above-mentioned part I was not running on any other error, so for the sake of readability I cut off some of the lines .... and forgot to remove the Pi thing Anyway, thanks a lot ...

6. Originally Posted by Andi Rrashi
Thank you for your replies. I actually guessed there would be something wrong with floating point numbers but I couldn't figure out the solution. The 'small tolerance' solution is great. Thanks again ...
Do note that you need a small modification to TheBigH's solution, specifically you need to use fabs (if not, and if a >> b, then you would get a false positive):
Code:
```if (fabs(a - b) < EPSILON)
// numbers are "equal"```