Using a Taylor series to find sin(x) in C - c

I have an assignment where my professor wants us to calculate sin(x) using a taylor series. He wants us to stop the iterations when the difference between two consecutive fractions is less than 10^-6.
I ended up approaching the problem by saying that for example x^5/5! is the same as (x^3/3!) * (x^2/4*5) and that this is true for all the fractions. So I can just keep the previous fraction I calculated and use it on the next iteration. Problem is the number I end up with is a bit off from its actual sin and I can't figure out why.Thanks in advance. Here is my code:
#include <stdio.h>
#include <Math.h>
#define pi 3.14159265358979323846
int main(int argc, int **argv){
int sign = -1, pwr = 3;
double previous, current, rad,sum, degr;
printf("Calculating sin using Taylor Series\n\n");
printf("Give degrees: ");
scanf("%lf", &degr);
// translate to rads
rad = degr*(pi/180);
sum = rad;
previous = rad;
do{
current = (previous * pow(rad, 2))/(pwr* pwr-1);
sum += sign*current;
pwr += 2;
sign *= -1;
}
while(abs(current - previous) > pow(10, -6));
printf("The sin of %lf degrees is ", degr);
printf("%.6f\n", sum);
printf("%.6f", sin(rad));
return 0;
}

You're using the abs function, which expects an int and returns an int. This results in the loop existing if the difference between the current and prior term is less than 1 as it will set diff to 0.
Instead, you want fabs which expects and returns a double.

Related

how do i print out the avarage of several arrays with float?

i'm just starting with getting to know C, and i'm now following the cs50 course. i have a question on the following code.
I want to calculate the avarage score of the user input.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int s = get_int("how many scores? ");
int sum = 0;
int score[s];
for(int i = 0; i < s; i++)
{
score[i] = get_int("score: ");
sum = sum + score[i];
}
float avg = sum / s;
printf("avarage: %f\n", avg);
}
So, it prints the avarage, but gets round down to .0000.
Is it because i am using a int to divide by? i have tried several things, like changing int to float, but without result.
How do I solve this?
This is an integer division:
float avg = sum / s;
Which means that 3 / 2 will be 1 (the decimal part is discarded). This will then be stored in avg as 1.f.
You need to make it into a floating point division. You can cast one of the operands to the desired type:
float avg = (float)sum / s;
Now both operands (sum and s) will be converted to float before the actual division takes place and the correct result will be shown, which is 1.5 + some zeroes in the example above.
#Ted's answer (integer division) is the reason your results were not as expected.
For your consideration, I've rewritten your code to be more concise. (The less code there is, the easier it can be to read and understand (as you learn more about C.))
#include <cs50.h>
#include <stdio.h>
int main() // 'void' is unnecessary
{
double sum = 0.0; // make the accumulator floating point
int s = get_int( "how many scores? " );
for(int i = 0; i < s; i++) // no need for braces when...
sum += get_int( "score: " ); // everything happens on one line
/* Above: you may not have seen "+=" before. Find out. Aids clarity */
printf("avarage: %lf\n", sum / s ); // float division result is printed.
}
And, the same thing again to compare without comments
#include <cs50.h>
#include <stdio.h>
int main()
{
double sum = 0.0;
int s = get_int( "how many scores? " );
for(int i = 0; i < s; i++)
sum += get_int( "score: " );
printf("avarage: %lf\n", sum / s );
}

Math expression with cos() not returning expected value

I'm trying to use cosine and sine, however they do not return the value I'm expecting.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main() {
float magnitudeForce;
int force;
float theta;
float angle;
double x;
double y;
int i = 0;
while(i < 3){
printf("Please enter the value of the force"
" and the angle from the x-axis of the force:\n");
scanf("%d %f", &force, &angle);
printf("The force and the angle are: %d %.2lf.\n", force, angle);
x = force * cos(angle);
printf("%lf\n", x);
++i;
}
return 0;
}
So if the force is 8 and the angle 60 then the return should be 4, but it is returning -7.62.
The C cos function requires its argument to be in radians rather than degrees.
While the cosine of sixty degrees is 0.5, the cosine of 60 radians is about -0.95, which is why you're seeing -7.62 when you multiply it by eight.
You can fix this by doing something like:
x = force * cos(angle * M_PI / 180.0);
Keep in mind that M_PI is a POSIX thing rather than an ISO thing so it may not necessarily be in your C implementation. If it's not, you can just define it yourself with something like:
const double M_PI = 3.14159265358979323846264338327950288;

Calculate cosine with sum of addends

Need some help with a task from my homework.
They gave us a series to calculate cosine, which is:
Σ(-1)^ix^2i/(2i)!
And the task is to implement this in C program by writing a function that takes angle x, and calculate it's cosine. The series should continue summing until the next addend in the series is less then 1.0e-6 (0.000001). I did this and it works good only for small numbers, if I put big numbers as angle, the program get stuck.
#include <stdio.h>
#include <math.h>
#define PI 3.141592
double my_cos(double angle);
int main() {
double angle, radian, my_res, their_res;
printf("Please type a number... \n");
scanf("%lf", &angle);
radian = angle * (PI/180);
my_res = my_cos(radian); /* result from my custom cosine function */
their_res = cos(radian); /* result from the cos function located in the library math.h */
printf("My result is: %f \nMath.h library result is: %f \n", my_res, their_res);
return 0;
}
.
#include <math.h>
#define ACCURACY 1.0e-6
long factorial(int x);
double my_cos(double angle){
int i = 0;
double sum = 0, next_addend;
do {
next_addend = pow(-1, (i+1)) * pow(angle, 2*(i+1)) / factorial(2*(i+1));
sum += pow(-1, i) * pow(angle, 2*i) / factorial(2*i);
i++;
} while ( ACCURACY < fabs(next_addend) );
return sum;
}
/* return the factorial of a given value */
long factorial(int x){
if ( x == 0 ) {
return 1;
}
return(x * factorial(x - 1));
}
If I run the program and insert 45:
But if I insert 300, the program is just "waiting":
I guess it related somehow to the factorial function?
I will really appreciate your help..
Depending on whether sizeof(long) is 4 or 8 on your system you can only calculate 12! or 20! inside a long. Also, calculating multiple pow at every iteration is very inefficient.
For a better solution, try to find out how to calculate the next_addend if you know the previous addend (hint: calculate their ratio on a piece of paper).

the usage of the long double

The functions purpose is to calculate the square root of a number using the Newton-Raphson method. I included a printf routine in the while loop so I can see the value of root 2 get closer and closer to the actual value. I originally used float to define epsilon but as I increased the value of epsilon, the value of the return results seem to be cut-off after a certain number of digits. So I decided to switch all the variable to long double, and the program is displaying negative results. How do I fix it?
//Function to calculate the absolute value of a number
#include <stdio.h>
long double absoluteValue (long double x)
{
if (x < 0)
x = -x;
return (x);
}
//Function to compute the square root of a number
long double squareRoot (long double x, long double a)
{
long double guess = 1.0;
while ( absoluteValue (guess * guess - x) >= a){
guess = (x / guess + guess) / 2.0;
printf ("%Lf\n ", guess);
}
return guess;
}
int main (void)
{
long double epsilon = 0.0000000000000001;
printf ("\nsquareRoot (2.0) = %Lf\n\n\n\n", squareRoot (2.0, epsilon));
printf ("\nsquareRoot (144.0) = %Lf\n\n\n\n", squareRoot (144.0, epsilon));
printf ("\nsquareRoot (17.5) = %Lf\n", squareRoot (17.5, epsilon));
return 0;
}
If you are using the version of Code::Blocks with mingw, see this answer: Conversion specifier of long double in C
mingw ... printf does not support the 'long double' type.
Some more supporting documentation for it.
http://bytes.com/topic/c/answers/135253-printing-long-double-type-via-printf-mingw-g-3-2-3-a
If you went straight from float to long double, you may try just using double instead, which is twice as long as a float to start with, and you may not need to go all the way to a long double.
For that you would use the print specifier of %lf, and your loop might want to look something like this, to prevent infinite loops based on your epsilon:
double squareRoot ( double x, double a)
{
double nextGuess = 1.0;
double lastGuess = 0.0;
while ( absoluteValue (nextGuess * nextGuess - x) >= a && nextGuess != lastGuess){
lastGuess = nextGuess;
nextGuess = (x / lastGuess + lastGuess) / 2.0;
printf ("%lf\n ", nextGuess);
}
return nextGuess;
}

Getting the fractional part of a double value in integer without losing precision

i want to convert the fractional part of a double value with precision upto 4 digits into integer. but when i do it, i lose precision. Is there any way so that i can get the precise value?
#include<stdio.h>
int main()
{
double number;
double fractional_part;
int output;
number = 1.1234;
fractional_part = number-(int)number;
fractional_part = fractional_part*10000.0;
printf("%lf\n",fractional_part);
output = (int)fractional_part;
printf("%d\n",output);
return 0;
}
i am expecting output to be 1234 but it gives 1233. please suggest a way so that i can get desired output. i want the solution in C language.
Assuming you want to get back a positive fraction even for negative values, I'd go with
(int)round(fabs(value - trunc(value)) * 1e4)
which should give you the expected result 1234.
If you do not round and just truncate the value
(int)(fabs(value - trunc(value)) * 1e4)
(which is essentially the same as your original code), you'll end up with the unexpected result 1233 as 1.1234 - 1.0 = 0.12339999999999995 in double precision.
Without using round(), you'll also get the expected result if you change the order of operations to
(int)(fabs(value * 1e4 - trunc(value) * 1e4))
If the integral part of value is large enough, floating-point inaccuracies will of course kick in again.
You can also use modf() instead of trunc() as David suggests, which is probably the best approach as far as floating point accuracy goes:
double dummy;
(int)round(fabs(modf(value, &dummy)) * 1e4)
number= 1.1234, whole=1, fraction=1234
int main()
{
double number;
int whole, fraction;
number = 1.1234;
whole= (int)number;
fraction =(int)(number*10000);
fraction = fraction-(whole *10000);
printf("%d\n",fraction);
printf("%d\n",whole);
return 0;
}
A solution for any number could be:
#include <cmath>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
float number = 123.46244;
float number_final;
float temp = number; // keep the number in a temporary variable
int temp2 = 1; // keep the length of the fractional part
while (fmod(temp, 10) !=0) // find the length of the fractional part
{
temp = temp*10;
temp2 *= 10;
}
temp /= 10; // in tins step our number is lile this xxxx0
temp2 /= 10;
number_final = fmod(temp, temp2);
cout<<number_final;
getch();
return 0;
}
Use modf and ceil
#include <stdio.h>
#include <math.h>
int main(void)
{
double param, fractpart, intpart;
int output;
param = 1.1234;
fractpart = modf(param , &intpart);
output = (int)(ceil(fractpart * 10000));
printf("%d\n", output);
return 0;
}

Resources