0

I'm creating a simple program which will check whether the value of sin and cosine of an angle is equal to 1 or not i typed this code

#include <stdio.h>
#include <math.h>
int main()
{
    int x;
    printf("Enter the value of angle in degree: \n");
    scanf("%d",&x);
    double rad = 0.0174533*x;
    double sum = pow(sin(rad),2) + pow(cos(rad),2);
    printf("%f",sum);
    if (sum == 1)
        printf("\nsum of squares of sine and cosine is equal to 1");
    else
        printf("\nsum of squares of sine and cosine is not equal to 

1"); return 0; and it says the sum is not equal to 1 that is the else block is executed while if i change the code to

#include <stdio.h>
#include <math.h>
int main()
{
    int x;
    printf("Enter the value of angle in degree: \n");
    scanf("%d",&x);
    double rad = angle*3.14/180;
    double sum = pow(sin(rad),2) + pow(cos(rad),2);
    printf("%f",sum);
    if (sum == 1)
        printf("\nsum of squares of sine and cosine is equal to 1");
    else
        printf("\nsum of squares of sine and cosine is not equal to 1");
return 0;

It works fine how??

  • I would assume it is because of the precison. `0.0174533` does not not have the same precision as `3.14/180` – PhoenixBlue Oct 25 '19 at 10:41
  • but when i print sum it gives 1 as output – Tushar Sharma Oct 25 '19 at 10:44
  • @TusharSharma try this ```printf( "%1.12lf", sum );``` and you will probably see that the ```sum``` is not 1 (if 12 decimals are enough) – John Doe Oct 25 '19 at 10:46
  • That's because `printf` rounds the value, but is not exactly `1.0`. Please see [Is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) and [Why Are Floating Point Numbers Inaccurate?](https://stackoverflow.com/questions/21895756/why-are-floating-point-numbers-inaccurate) Also function `pow()` is reputed to be not very accurate, and is unneccessary to compute a square anyway. – Weather Vane Oct 25 '19 at 10:51
  • Note that `math.h` probably has a more accurate value of *π* (such as `#define M_PI 3.14159265358979323846`) but it's academic here, because you are using the same angle for `sin()` and `cos()` even if it is not very accurate. – Weather Vane Oct 25 '19 at 11:01
  • The second source code does not compile because `angle` is not defined. When asking question, copy and paste the **exact** source code used. – Eric Postpischil Oct 25 '19 at 12:35

2 Answers2

1

There are two reasons that calculating the sum of the squares of the sine and the cosine of an angle using floating-point arithmetic may not produce exactly 1:

  • Floating-point arithmetic only approximates real arithmetic. Since a floating-point format can only represent certain values, the real-number result of any mathematical operation is rounded to the nearest value representable in the floating-point format.
  • Calculating sine, cosine, and exponentiation is somewhat hard, and the implementations of the sin, cos, and pow routines may have errors (greater than those necessitated by the floating-point format).

Those issues cause errors in the arithmetic. Those errors might or might not cancel out, so the final result might or might not be 1.

When formatting a floating-point number using %f, the default precision is six digits after the decimal point. To see the difference between 1 and the representable values closest to 1 in the double format, you need 16 digits after the decimal place. (This assumes the IEEE-754 basic 64-bit binary format is being used for double, which is very common.) In general, you need 17 significant digits to uniquely distinguish the specific value. (This number is given by DBL_DECIMAL_DIG, defined in <float.h>.)

If you format the numbers with printf("%.16f", sum);, you will see the differences.

Although the variations due to rounding can be analyzed, they often behave similarly to random fluctuations. So slight changes in the arithmetic used can cause different results. In this case, the difference between 0.0174533 and 3.14/180 caused the angle to be slightly different, which resulted in slightly different calculations.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
-1

Probably when you use

double rad = 0.0174533*x
double sum = pow(sin(rad),2) + pow(cos(rad),2);
printf("%f",sum);

due to the precision of the multiplication with x the value of sum won't be exactly 1.

When you use

printf("%f",sum);

you see 1 because the default precision when printing a float is 6 decimal digits, if sum has more than those it gets truncated. This means that 1.00000001 or 0.9999999 will be both printed as 1 but the if check will fail because they are not actually equal to 1.

To print the float with an higher precision you can use the formula:

printf( "%1.12lf", sum );

where the first 1 after the % is the number of digits in the integer part of the number while the value after the . is the number of digits you want in the decimal part.

John Doe
  • 1,613
  • 1
  • 17
  • 35
  • Mathematically, multiplication with `x` is irrelevant, because the sum of the squares of the sine and the cosine of **any** angle is 1. The actual cause of the sum not being 1 is that the `sin`, `cos`, `pow`, and `+` operations only approximate real arithmetic. Whether they get exactly 1 as a result may be effectively random due to happenstance of the approximations, so changing the angle may change the result, but it is not properly the cause. – Eric Postpischil Oct 25 '19 at 11:00
  • @EricPostpischil i agree, he asked why in the first case the condition is false even if printf shows 1 and i wrote why this happens and how to see the "real" value. Being the multiplication the only line different in the two examples i thought it would be helpful to indicate it as a **possible** cause for the difference because i don't think it's useful to only say "it's different because floats don't do what you think" – John Doe Oct 25 '19 at 11:07
  • The statement “It’s different because floats don’t do what you think” is true. The statement “Probably when you use … due to the precision of the multiplication with x the value of sum won't be exactly 1.” is false. Giving a true answering may not be greatly useful if the reader does not understand it, but it can be explained. Giving a false answer is not useful. – Eric Postpischil Oct 25 '19 at 12:22