sin function not working as expected - c

I have this equation its output using a sci calc is : 0.017... but when i run it in c its output is :0.84..
The input is 1
Equation is: sin(x) - x^4 + 1
float sinp(float p1)
{
float fop;
float ppowers;
printf("%f",p1);
ppowers = pow(p1,4);
fop = sin(p1)-ppowers+1;
return (fop);
}
is there a reason behind this like would it be because of rad or in degree?
I havent really used the sin or any math function of C that much so I don't really get whats wrong here. Google gave me .84 as an aswer but my calc gives me .017 which is really confusing since I need to get the same output with my calc.
Thank you all :)

In mathemtics and in all computer languages trigonometric functions work in radians. If you want to work in degrees you should make the conversion (or define your own sin_degrees function) like:
double sin_degrees(double degrees) {
return sin(degrees * (M_PI/180.0);
}

I am guessing google uses degrees as angle measure in sin, while c++ uses radians and that is the reason for the difference. To convert an angle in degrees to same value in radians to the following:
rad_angle = deg_angle * (PI / 180.0);
Where PI it the good old constant you know.

Related

weird result when cos is 0

hello i am writing basic calculator. everytime i use 90 degrees on cos function it gives -0 as result
int deg;
float rad,result;
printf("\ndegree\n");
scanf("%d",&deg);
rad = deg * (M_PI/180);
result=cos(rad);
printf("\nresult= %f",result);
result
i dont even know what to try.
i just googled it and did not see any similar results.
M_PI is defined as 3.141593... which is slightly over PI, consequently, the cos(90.xxx) is lesser than 0.
If you try with 3.1415926, you will get positive result:
https://onlinegdb.com/7MWNEkkqI
None of those two values match the real PI value, and they might even be defined differently on different compilers. The point is that having one above the real PI and the other below the real PI make them to fall in different quadrants, and a different sign on the result.
The float being represented by 32bit, it is not possible to represent exactly most of the real numbers (except those few ~2^32 values). And going to double will not solve this.
At the end, it is the function converting the number to a string for representation on the screen who can detect that "-0" and write "0" instead. That is why if you open most applications, you don't get "-0" very often.
The solution is to have the "print" (note, that this is not necessarily the official printf ) which is aware of the number of relevant bits, and can convert this -0.0000000x to 0; 0.9999999x to 1, etc.. Modern "print" functions will provide a mechanism to set the precision (for example std::setprecision in C++).
Note: rounding the value will not work with very big or small numbers.
Other answers have suggested changing the value of pi slightly.
Other answers have suggested changing type float to type double.
Both of these suggestions move the problem around slightly, perhaps changing the objectionable displayed value of -0 to plain 0.
(And switching from float to double is almost always a good idea, no matter what.)
But none of these suggestions actually "solve" this particular "problem", because fundamentally there is no actual problem here.
The real issue, as I said in a comment, is that it is just not possible to compute the cosine of 90.0000000000 degrees, at all, because you are never going to be able to represent the value π/2 perfectly accurately in radians. You're inevitably always going to be working with the equivalent of 89.9999999999 degrees, or 90.0000000001 degrees, so to speak. That is, the problem isn't that cos() is computing the wrong value; the problem is that you're not even passing it the "right" value to begin with! And when π/2 comes out a little bit over, meaning that cos() ends up computing a value like -0.0000000001, a high-quality version of printf is going to round and display it as -0, because -0 is a thing in computer floating point.
If you have a "fixed" version of the original program that no longer displays cos(90) as -0, I suggest trying it with cos(-90), or cos(270) — I bet one or the other of those will display -0, so you're right back out of the frying pan and into the fire again.
If you have a requirement that says you must never display "-0", I believe you would want to pursue a completely different approach, perhaps something along the lines of
char tmp[50];
snprintf(tmp, sizeof(tmp), "%f", result);
if(*tmp == '-' && atof(tmp) == 0) result = -result;
printf("result = %f\n", result);
It may seem strange to be tinkering around with the string representation like this, but it actually makes sense, because it's only after converting (and perhaps rounding) to a string representation that we can be sure we've got the "-0.000000" case that needs special attention.
If you use %g instead of %f, you would see that the result is not exactly 0, but a very small, negative value. Hence the minus sign with %f.
Now, for a more accurate result, you should use the type double instead of float for the variables rad and result (cos already takes a double and returns a double). The sign will be positive, but the result will still not be 0 exactly. As π/2 is irrational, there is no way to get an exact 0 with the cos function (unless its implementation is buggy).
The next C standard (C23) will include a cospi function (as recommended by the IEEE 754 standard), which could solve your issue as it is defined as cospi(x) = cos(πx). So, for 90 degrees, you would call cospi with the argument 0.5, which is exactly representable.
EDIT: Some implementations may be tempted to hide the issue by guessing what the result should be, such as assuming that if the cos argument is very close to π/2, then it is regarded as π/2 exactly, so that an exact 0 is returned. This is a bad idea (in particular for generic libraries like the C library), which could yield surprising results. Even user code should be careful. See this video to see possible consequences of such hacks on a Casio calculator.
cos(90) is exactly 0. Purely mathematically, 0 is equal to -0. I assume that the problem is the minus sign?
M_PI is of type double, with the value 3.14159265358979323846, which is slightly less than true pi.
Converting it to a float makes it 3.1415927410125732421875, which is slightly more than true pi. The calculations could be done in type double, and converted to float afterwards? That code would of course be slightly less efficient, but depending on the use case, it would probably not matter, and the risk for any similar errors would be minimized.
EDIT: I just realized M_PI exists as a float too, depending on the library, as previous answer states. Both ways should solve the problem.
everytime i use 90 degrees on cos function it gives -0 as result
Rounded text
The result is not -0 but a value between 0.0 and -0.0000005 that when printed using "%f" (in the form d.dddddd) OP saw a rounded value as "-0.000000".
To see a more informative output, use "%g".
printf("\nresult= %g",result);
// result= -4.37114e-08
Related graphic
Why -4.37114e-08?
rad = deg * (M_PI/180); attempts to convert degrees to radians using an approximation to π. π is irrational. All finite floating point values are rational and so M_PI is never exactly π, regardless how precise the floating point type. Thus rad = deg * (M_PI/180); introduces small errors that are magnified in cos(rad) when it performs it argument range reduction.
There is an alternative. Perform the argument range reduction in degrees, which can be exact, scale and then call cos().
#include <math.h>
#include <stdio.h>
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
static double d2r(double d) {
return (d / 180.0) * ((double) M_PI);
}
double cosd(double x) {
if (!isfinite(x)) {
return cos(x);
}
int quo;
double d_45 = remquo(fabs(x), 90.0, &quo);
// d_45 is in the range [-45...45]
double r_pidiv4 = d2r(d_45);
switch (quo % 4) {
case 0:
return cos(r_pidiv4);
case 1:
// Add 0.0 to avoid -0.0
return 0.0 - sin(r_pidiv4);
case 2:
return -cos(r_pidiv4);
case 3:
return sin(r_pidiv4);
}
return 0.0;
}
Test
int main(void) {
int prec = DBL_DECIMAL_DIG - 1;
for (int d = -360; d <= 360; d += 15) {
double r = d2r(d);
printf("cos (%6.1f degrees) = % .*e\n", 1.0 * d, prec, cos(r));
printf("cosd(%6.1f degrees) = % .*e\n", 1.0 * d, prec, cosd(d));
}
return 0;
}
Ouput
cos (-360.0 degrees) = 1.0000000000000000e+00
cosd(-360.0 degrees) = 1.0000000000000000e+00
...
cos (-270.0 degrees) = -1.8369701987210297e-16
cosd(-270.0 degrees) = 0.0000000000000000e+00 // Exactly zero
...
cos ( 0.0 degrees) = 1.0000000000000000e+00
cosd( 0.0 degrees) = 1.0000000000000000e+00
...
cos ( 60.0 degrees) = 5.0000000000000011e-01 // Not 0.5
cosd( 60.0 degrees) = 4.9999999999999994e-01 // Not 0.5, yet closer
...
cos ( 90.0 degrees) = 6.1232339957367660e-17
cosd( 90.0 degrees) = 0.0000000000000000e+00 // Exactly zero, OP's goal
...
cos ( 270.0 degrees) = -1.8369701987210297e-16
cosd( 270.0 degrees) = 0.0000000000000000e+00 // Exactly zero
...
cos ( 360.0 degrees) = 1.0000000000000000e+00
cosd( 360.0 degrees) = 1.0000000000000000e+00

Why i have to declare constant Pi value to use Cos Function in Math.h?

x = 60.0;
val = PI / 180.0;
ret = cos( x*val );
printf("The cosine of %lf is %lf degrees\n", x, ret);
Hi, I was self-studying about function in math.h then i tried to use COS fuction to find the cos of radius in the program . I try to find the explantion of this function that Why COS function requires adding Pi/180.0 in Cos function to calculate cos of radius properly . Thank you so much
If you check the documentation, you'll see that cos() accepts an angle in radians, not degrees. By multiplying your angle of 60 degrees by PI / 180.0, you're converting it to radians.

Obtaining the decimal value of Cosinus phi

When I write on my calculator Cos45 I get a decimal number = 0.707
How do I produce such a number in C.
I tested this:
printf ("type a degree between 0 - 360:\n");
scanf ("%f",&float1);
printf ("cosphi = %f",cosf(float1));
but it gave an off number. It produced cosphi = 0.52
Your calculator is configured to compute trigonometric functions in degrees.
C's trig functions work in radians. (A full circle is 360 degrees, 2*pi radians.)
If you want to treat the input as degrees, you need to convert the value to radians before passing it to cosf(), by multiplying it by 180/pi.
I got it to work. Thanks a million :)
#include <stdio.h>
int main ()
//Convert Trigonometric Angles into Decimals and Radians.
//Radians are number of Radiuses that are wrapped around the circumference.
//Pi for half the circle, Radius is wrapped 3.14 times on 180 degrees. r2=d1 .
//Circumference = 2radius * Pi = Diameter * Pi = 2Pi * radius .
//KHO2016.no2. mingw (TDM-GCC-32) . c-ansi .
{
//Declare
float flp1, flp2, flp3, flp4, pi;
int int1;
//valuate
pi = 3.141592654;
int1 = 180;
//calculate
printf ("type a degree between 0 - 360 : ");
scanf ("%f",&flp1);
flp2=int1/flp1; // 180 is divided by desired angle
flp3=pi/flp2; // Pi is divided by the result of 180 / desired angle = Radians
flp4=cosf(flp3); // Result of Pi divided by Radians and fed into the Cosf Radian modulus
printf ("The Decimal value of Cosinus %.1f degrees = %.3f\n",flp1,flp4);
printf ("Angle typed in Radians = %f",flp3);
//Terminate
return 0;
}
As answer well by #Keith Thompson, the C function works in radians and so a degrees to radian conversion is needed.
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
float angle_radians = angle_degrees * (float) (M_PI/180.0);
Yet rather that directly scale by pi/180.0, code will get more precise answers, for angles outside a primary range, if code first does range reduction and then scales by pi/180.0. This is because the scaling of pi/180.0 is inexact as machine pi float pi = 3.14159265; is not exactly mathematical π. The radian range reduction, performed by cos(), is in error as the computed radian value given to it is inexact to begin with. With degrees, range reduction can be done exactly.
// Benefit with angles outside -360° to +360°
float angle_degrees_reduce = fmodf(angle_degrees, 360.0f);
float angle_radians = angle_degrees_reduce * M_PI/180.0;
sind() is a sine example that performs even better by reducing to a narrower interval. With angles outside the -45° to +45° range, there is benefit.

Determining angle of line

In Silverlight, is there a way to determine the angle of a Line object? If I have a Line with coordinates of 0,0 - 30,80, is there a way to determine the angle, in degrees, that the line is running?
You could try finding the arc tangent using the Math.Atan function. You just need to find the atan of the (delta of) y-value over the (delta of) x-value.
The answer will be in radians and you will need to convert it to degrees (rads * (180f / Math.PI)).
An example of this would be something like:
double rads = Math.Atan((line.Y2 - line.Y1) / (line.X2 - line.X1));
double degrees = rads * (180f / Math.PI);
(Note: I've never used Silverlight and I'm just basing this off the docs, so this might be completely wrong... you can also use Math.Atan2(delta y, delta x) too...)

cos result incorrect

I import "math.h".
I can use the cos function,
but when I execute cos(0.321139585333178)
the result is 0.948876
If I use the calculator in Mac or use a normal calculator, the result is 0.999984292347418
Can anyone help me to solve that problem?
You're confusing degrees with radians.
cos(0.321139585333178 degrees) = 0.999984292
cos(0.321139585333178 radians) = 0.948876326
To convert from radians to degrees, multiply by 180/π.
To convert from degrees to radians, multiply by π/180.

Resources