Obtaining the decimal value of Cosinus phi - c

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.

Related

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.

precision issuse with taylor series for finding cosine

I've created a function to compute cosine based on taylor serie ,
only to encounter a precision problem when comparing it with the standard library cosine.
for example,computing 23 my cos gives:
-0.532834
and the standard library gives:
-0.532833
I've been searching the web,and trying to figure it myself but just couldn't figure what the problem is!
when increasing the treashould to be 1.0e-7,the problem is solved.
but it should work well for 1.0e-6 as well(as it worked for my friends)
would appreciate any insight,thanks ahead.
#define PI 3.14159265358979323846264338327950288419716
double my_cos(double rad){
int i = 0;
double numer = 1, denom = 1;
double x2, cos = 0;
rad = fmod(fabs(rad),2*PI);
x2 = pow(rad,2);
do{
cos += pow(-1,i)*(numer/denom);
i++;
numer *= x2;
denom *= (2*i)*(2*i-1);
} while (numer/denom>1.0e-6);
return cos ;
}
The rounding happens when you call printf
This
printf("%f\n", my_cos(23));
printf("%f\n", cos(23));
will print
-0.532834
-0.532833
which seems "wrong".
But
if you increase the number of digits print like
printf("%0.12f\n", my_cos(23));
printf("%0.12f\n", cos(23));
it will print
-0.532833931872
-0.532833020333
So you have the precision you want. It's just the printing that makes it look as if something is wrong.

Modelling a Pendulum in C

This is my code for attempting a while Loop to model a pendulum swing, however the values produced don't seem to help me:
#include <stdio.h>
#include <math.h>
#define PI 3.14159265
main()
{
float theta = 0; // initial value for angle
float omega = 0.2; // initial value for angular speed
float time = 0; // initial time
float dt = 0.01; // time step
while (theta < 2 * PI && -2*PI) {
time = time + dt;
theta = theta + omega*dt;
printf("theta=%i, omega=%i, time=%i, and dt=%i\n", theta, omega, time, dt);
}
system("PAUSE");
}
How can I modify this to be more helpful? The while condition I have to use is that it should stop when the pendulum has made one revelation either forwards or backwards (-2PI or 2PI). I need to use the formula 'omega=omega-(g/l)dtsin(theta)' and NOT make the assumption that theta approximately equals sin(theta).
while(theta <2*PI&&-2*PI)
In c if we want to combine multiple expressions we can combine them using logical operators as
while((theta < 2 * PI) && (theta > -2 * PI))
PS- I am no physics expert. Change conditions as per your requirement
There are some problem in this code :
According to the standard you shouldn't use
main()
But either
int main()
int main(void)
int main(int argc, char *argv[])
Also don't forget
return 0;
Sample program :
#include <stdio.h>
int main(void) {
/* Do stuff */
return 0;
}
If you wish to read more information about that, click here.
As LutzL pointed out you should use M_PI instead of your definition of PI. Just #include <math.h>
That's how you would print the value for example :
printf("\nValue of M_PI is %f\n\n", M_PI);
Read more here.
As pointed out by rootkea :
In c if we want to combine multiple expressions we can combine them
using logical operators as
while((theta < 2 * PI) && (theta > -2 * PI))
If you want greater precision (I think that this is the case) you should use double instead of float.
You are trying to print float variables with the "%i" format specifier. That's wrong, "%i" is used to print int signed integer and using the wrong specifier invokes undefined behavior. You should use "%f" to print float or double signed decimal.
Have a read about printf format specifiers here.
The angle equation that you use is not right. According to your expression it changes linearly with time, although the equation is harmonic:
θ = θ0cos(ωt)
where ω = g/L, L is the length of the pendulum and g the acceleration due to gravity.
Where thetaMax is the max deflection angle, g is gravity const, L is length of pendulum and t is time. So, you want to know thetaMaxfrom energy conservation law, for example.
Alrught, let's revise energy conservation law here:
As you know Potential energy at max deflection equals Kinetic energy at the lowest point of the pendulum path:
KE = ПE
m*g*L*sin(thetaMax) = m*sqr(omega)*sqr(L)/2
Approximately, for small angles:
m*g*L*thetaMax = m*sqr(omega)*sqr(L)/2
thetaMax = sqr(omega)*L/(2*g)
that is it. Here is code that calculates this type of oscillatory motion. All absolute values:
#include <stdio.h>
#include <math.h>
#define PI 3.14159265
#define L 1 //length of the pendulum
#define g 9.8 //gravity const
int main()
{
double theta = 0; // initial value for angle
double omega = 0.2; // initial value for angular speed
double time = 0; // initial time
double dt = 0.01; // time step
double thetaMax = omega*omega*L/(2*g);
while (theta < thetaMax) {
time = time + dt;
theta = thetaMax * sin(omega*time);
printf("theta=%f, omega=%f, time=%f, and thetaMax=%f\n", theta, omega, time, thetaMax);
}
return 0;
}
It is going to calculate these parameters infinitely, so just limit theta in the condition of the while-loop to a desired angle of deflection.
The idea of modelling, in simple terms, involves finding a mathematical representation of a physical phenomenon. In other words you need to "find" an equation that represents all the observable properties of the object in context, in your case a pendulum1.
All you need to describe a pendulum is its equation of motion. To find it you firstly try to qualify the motion, by observing it:
If you try to displace it (many times with a very small angle) from its equilibrium point, you will mostly observe few swings, along the same path, where its amplitude decreases and it is brought back to its stable equilibrium, as if by some kind of restoring force, in other words the pendulum performs regular and repeating motion, called periodic motion
Thus, you are looking for a mathematical function that can represent a periodic motion, as it turns out a great candidate for this role are the trigonometric functions: sin and cos, that have the needed property i.e. repeat themselves with a period T.
To find and quantify this restoring force you use Newton's Second Law, where after you express everything in terms of the very small angle theta << 1 (that allows using of the small-angle approximation: sin(theta) = theta) of displacement theta, you get the wanted equation of motion, which is represented by the following differential equation:
with a great surprise (and to the first order of approximation), when you solve the above equation you find:
which approximately2 matches the predictions from your observations (with some random error (standard deviation), preferably not systematic), i.e. the motion of the pendulum is described by the cosine function, it has periodic motion with an amplitude equal to the initial displacement and a period equal to:
and here is the catch,
the above equation for theta describes a pendulum that does not lose energy and its values repeat infinitely and that is why the loop in your program is an infinite loop harmonically oscillating pun intended with the same values!
If you want to observe a motion that slowly stops you need to add an additional damping force that will slowly subtract energy from the system. This damping force is represented by the following additional term in the equation of motion:
that again, can be expressed in terms of the angle theta. Now, when you solve the equation of motion, the amplitude gets multiplied by:
where b is the damping constant from which it depends how fast the motion will stop.
As a consequence of the above,
if you want to see something similar to the real pendulum you need to include this last exponential to your equation.
To do this just follow the great explanation offered by #Petr Stepanov, modifying thetaMax to include the above exponent.
#include <stdio.h>
#include <math.h>
#define PI 3.14159
#define E 2.71828 // Euler's number
#define L 1 // length of the pendulum
#define g 9.80665 // gravity const
int main() {
double theta = 0.0; // initial value for angle
double omega = 0.2; // initial value for angular speed
double time = 0.0; // initial time
double dt = 0.01; // time step
double b = 0.5; // modified damping constant
double thetaMax = omega * omega * L / (2 * g);
while (theta < thetaMax) {
time = time + dt;
theta = thetaMax * ldexp(E, (-b) * time) * sin(omega * time);
printf("Deflection angle=%f, Angular frequency=%f, Time=%f\n", theta, omega, time);
}
return 0;
}
1. An object with mass m, hung on a fixed point with a non-elastic, "massless" thread with length l , that allows it to swing freely in a gravitational field, quantified by the gravitational acceleration constant g.
2. It should be noted that: "all models are wrong; the practical question is how wrong do they have to be to not be useful"
The equation for a (simple, point mass on string) physical pendulum is
θ'' + k·sin(θ) = 0
where the constant:
k = g / L
contains gravitational g and length L.
θ is the angle measured from the position of rest, which of course is pointing down, that is, in a Cartesian coordinate system with the usual angle convention, at -90°. Thus the pendulum oscillations translate to theta oscillations around zero.
You could solve that (conservative) differential equation using symplectic Euler or Verlet/Leapfrog. Symplectic Euler in one variant has the loop (using ω=θ', that is, (θ',ω')=(ω, -k·sin(θ))
for(...) {
omega -= k*sin(theta) * dt;
theta += omega * dt;
t += dt;
printf(...);
}

float vs. double strange behaviour in c

i have troubles implementing a simple training program in C. The program should calculate a random cosinus or sinus of an angle, print the question "calculate cosinus/sinus of the angle x" to the user, who should type in the right answer in form "factor sqrt(value)". i.e. for cos(0) the user should type 1, for sin(45) the user should type 0.5sqrt(2). Most of the code is given in this task. The program doesn't work properly - for cos(270) the right answer is meant to be -0.000. Why is this happening? Why doesn't this code screams "division by 0"? Furthermore according to the task description the variable right should be of type double and rueckgabe of type int. But when i use double instead of float, i just get very high values (like 21234 or -435343). If i would use int as a return value of get_user_input(), the program won't work, right?
Here's the code:
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#define PI (acos(-1))
#define ACCURACY 1e-4
float get_user_input(is_cos, angle){
if (is_cos == 1) {
printf("Berechnen Sie den Cosinus zu %i\n", angle);
}
else {
printf("Berechnen Sie den Sinus zu %i\n", angle);
}
float faktor, wurzel=1.;
float rueckgabe;
scanf("%fsqrt(%f)", &faktor, &wurzel);
rueckgabe = faktor * sqrt(wurzel);
return rueckgabe;
}
int main (){
float right;
int correct;
int angles[] = { 0, 30, 45, 60, 90, 180, 270, 360 };
srand ( time(NULL) );
int is_cos = rand()%2;
int angle = angles[ rand()%(sizeof(angles)/sizeof(int)) ];
if( is_cos == 1) {
right = cos(angle/180.*PI);
}
else {
right = sin(angle/180.*PI);
}
correct = fabs(get_user_input(is_cos, angle)/right - 1.) <= ACCURACY;
printf("Ihre Antwort war %s!\n", correct ? "richtig" : "falsch");
return 0;
}
Since the sine and cosine return values in the range [-1, 1], I'd suggest that you use the absolute, rather than the relative, error. By replacing
correct = fabs(get_user_input(is_cos, angle)/right - 1.) <= ACCURACY;
with
correct = fabs(get_user_input(is_cos, angle) - right) <= ACCURACY;
everything should work as expected.
Generally I tend to use relative errors for large values and absolute errors for small values. You can combine both with
fabs(a-b)/(1.0+min(fabs(a), fabs(b)))
which (assuming you have a reasonable definition of min) tends to the relative error for large values and to the absolute error for small ones.
In your program, both divisor and dividend can be close to / exactly 0 at the same time.
Your program does not give you a "division by zero"-error, because by default most floating point implementations silently give you infinity/NaN/0/-0, depending on the exact values you divide.
The cosine to 270° is not exactly zero in floating-point arithmetic, because 270° cannot be expressed exactly in radians.
The following table shows the cosine of 270° (in the middle row) and in the first and last rows the cosines of the adjacent 32-bit floating-point numbers:
phi cos(phi)
4.7123885 -0.0000004649123
4.712389 0.000000011924881
4.7123895 0.00000048876205
And the same for 64-bit double-precision floating-point numbers:
phi cos(phi)
4.712388980384689 -1.0718754395722282e-15
4.71238898038469 -1.8369701987210297e-16
4.712388980384691 7.044813998280222e-16
With the current floating-point precision, there's no way that cos(phi) with phi in the vicinity of 1.5*pi can be exactly zero.
You could fix that by writing a cosdeg that takes an argument in degrees and returns exact values for the angles where the cosines and sines are -1, 0 or 1 and values calulated with radians otherwise. (Which then will happily generate the desired division by zero.)
The arguments to sin() and cos() are expressed in radians, not degrees.

sin function not working as expected

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.

Resources