Musfiq Rifat
Musfiq Rifat

Reputation: 43

Finding angles of triangle by given sides in C programming

I run it in my code::blocks to show 3 angles of triangle where 3 sides are given by the user. But if I run and give 3 sides such as 3,4,5 output will be -1.#J -1.#J -1.#J. What's wrong with my code?

#include <stdio.h>
#include <math.h>

int main()
{
    float a, b, c, A, B, C, R, s, pi, area;
    pi = acos(-1);

    scanf("%f %f %f", &a, &b, &c);
    s = (a+b+c)/2;
    area = sqrt(s*(s-a)*(s-b)*(s-c));

    R = (a*b*c)/(4*area);

    A = (180/pi)*asin(a/2*R);
    B = (180/pi)*asin(b/2*R);
    C =  (180/pi)*asin(c/2*R);

    printf("%.2f %.2f %.2f", A, B, C);


    return 0;
}

Upvotes: 3

Views: 9303

Answers (4)

user3629249
user3629249

Reputation: 16540

I could not get your posted code to work, even given all the comments and prior answers.

However, this works very well.

Note: I did not include code to error check the call to scanf() to keep the presentation simple

#include <stdio.h>
#include <math.h>

#define RAD_2_DEG  (57.2958)
#define TOTAL_DEG  (180.0)

int main( void )
{

    int  a, b, c;   // user entered lengths of sides of triangle
    double A, B, C; // calculated angle values in degrees

    scanf( "%d %d %d", &a, &b, &c );


    // note: acos returns the angle in radians
    //       and one radian is (approx) 57.2958 degrees
    A = RAD_2_DEG * acos((double)(b*b + c*c - a*a)/(2.0*b*c));

    B = RAD_2_DEG * acos((double)(c*c + a*a - b*b)/(2.0*a*c));

    // third angle done this way to absorb fractional degree errors
    C = TOTAL_DEG -(A + B);

    printf("%.2f %.2f %.2f", A, B, C);
    return 0;
}

Upvotes: 0

chux
chux

Reputation: 154242

Additional detail:

asin(x) is only defined for values [-1.0 ... 1.0]. With select input, corrected code may get a a/(2*R) that is just a little bit greater than 1.0 due to calculation issues with floating point.

s = (a+b+c)/2;

//  Jonathan Leffler tests

area = sqrt(s*(s-a)*(s-b)*(s-c));
R = (a*b*c)/(4*area);

// add test
double R2 = R*2.0;
A = (a>R2) ? 180/pi : (180/pi)*asin(a/R2);
...

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 755016

You need more parentheses. You have:

A = (180/pi)*asin(a/2*R);

You need:

A = (180/pi)*asin(a/(2*R));

What you wrote is equivalent to:

A = (180 / pi) * asin((R * a) / 2);

You should also check your inputs so that a 'triangle' with sides 1, 1, 3 is rejected, for example. Negative and zero lengths should probably be rejected too.

Revised code

#include <stdio.h>
#include <math.h>

int main(void)
{
    float a, b, c, A, B, C, R, s, pi, area;
    pi = acos(-1);

    if (scanf("%f %f %f", &a, &b, &c) != 3)
    {
        fprintf(stderr, "Failed to read 3 numbers\n");
        return 1;
    }
    if (a <= 0 || b <= 0 || c <= 0)
    {
        fprintf(stderr, "Sides must be strictly positive\n");
        return 1;
    }
    s = (a + b + c) / 2;
    if (a > s || b > s || c > s)
    {
        fprintf(stderr, "The three sides %.2f, %.2f, %.2f do not form a triangle\n",
                a, b, c);
        return 1;
    }

    area = sqrt(s * (s - a) * (s - b) * (s - c));

    R = (a * b * c) / (4 * area);

    A = (180 / pi) * asin(a / (2 * R));
    B = (180 / pi) * asin(b / (2 * R));
    C = (180 / pi) * asin(c / (2 * R));

    printf("Sides:  %6.2f %6.2f %6.2f\n", a, b, c);
    printf("Angles: %6.2f %6.2f %6.2f\n", A, B, C);

    return 0;
}

Note that error messages are reported on standard error. All lines of output end with a newline in the format. The input data is echoed. All of these are good practices.

Example runs

$ triangle <<< "0 1 3"
Sides must be strictly positive
$ triangle <<< "-1 1 3"
Sides must be strictly positive
$ triangle <<< "1 1 3"
The three sides 1.00, 1.00, 3.00 do not form a triangle
$ triangle <<< "3 4 5"
Sides:    3.00   4.00   5.00
Angles:  36.87  53.13  90.00
$ triangle <<< "3 3 3"
Sides:    3.00   3.00   3.00
Angles:  60.00  60.00  60.00
$ triangle <<< "1 1.4141 1"
Sides:    1.00   1.41   1.00
Angles:  45.00    nan  45.00
$ triangle <<< "1 1 1.4141"
Sides:    1.00   1.00   1.41
Angles:  45.00  45.00    nan
$ triangle <<< "1 1 1.414"
Sides:    1.00   1.00   1.41
Angles:  45.01  45.01  89.98
$ triangle <<< "1 1 1.41421356237309504880"
Sides:    1.00   1.00   1.41
Angles:  45.00  45.00    nan
$

I'm a little puzzled about the nan values. However, changing the data type from float to double and adjusting the scanf() formats appropriately (%lf instead of %f) seems to 'resolve' (maybe 'evade' is a better word) that problem.

Upvotes: 5

rango
rango

Reputation: 311

It should be

A = (180/pi)*asin(a/(2*R));

rather than

A = (180/pi)*asin(a/2*R);

Insufficient parentheses.

Upvotes: 1

Related Questions