We are doing C Programming in school and we have to calculate the cosine of a number with use of the "Taylor series" (https://en.wikipedia.org/wiki/Taylor_series). I know C programming but that what we have to do has not really much to do with programming itself more than being good in math.
If you put in your calculator cos(50) it's 0.6427.... That's what we have to do in C. There is the cos() function in math.h but that's not actually the cosine. I am overwhelmed with this and don't really know what we have to do. It should look something like this:
#include <stdio.h>
#include <conio.h>
#include <math.h>
int fac(int n);
double meincosinus(double x);
void main() {
double x;
double y;
int i;
printf("geben sie eine zahl ein\n");
scanf_s("%lf", &x);
y = meincosinus(x);
printf_s("cos(%lf)=%lf\n", x, y);
y = sin(x);
printf_s("cos(%lf)=%lf\n", x, y);
scanf_s("%d", &i);
printf_s("%d\n", i);
_getch();
}
int fac(int n) {
int prod = 1;
int i;
for (i = 1; i <= n; i++)
{
prod *= i;
}
return prod;
}
double meincosinus(double x)
{
double erg = 0;
int n;
for (n = 0; n <= x; n++)
{
x = fac(n);
erg += pow(-1, n) * pow(x, (2 * n)) / fac(2 * n);
}
return erg;
}
This code runs but the output is wrong.
Not an answer (but, well, I am a teacher myself, I am not gonna make your homework :)). But a few questions you should ask yourself and that might help you
Why are you comparing your Taylor computation of cosinus with the "real" sinus? Shouldn't y=sin(x) be y=cos(x), for a pertinent comparison?
why are you doing this: x = fac(n);? You are overwriting your x argument to "meinconsinus". You can't expect meincosinus(50) to really compute cos(50) if the first thing you do is overwriting that "50" with something else (namely n!).
also, why this for (n = 0; n <= x; n++). You know the Taylor formula better that I do (since you are studying it right now). It sure not supposed to stop after x iterations. x is rarely even an integer. It is supposed to be very small anyway. And could even be negative. So, question you've to ask yourself is, how many iterations (up to which term of the series) you want to compute. It is a rather arbitrary choice, since from Taylor point of view, answer is ∞. But on a computer, after a while it is no use to add extremely small numbers
Since I am mentioning the fact that x is supposed to be small: you can't compute cos(50) that way with a Taylor formula. You could compute cos(0.1) or even cos(1) maybe, with enough iterations. But 50 is not a small enough number. Plus, 50ⁿ will be very quickly out of control in your loop. If you really want meincosinus to be able to handle any number, you have first to reduce x, using trigonometric rules: cos(x)=cos(x)-2π; cos(x)=-cos(x); cos(x)=sin(π/2-x); ... There are some better rules, but with those simple ones, you can have x in [0,π/4]. Since π/4<1, at least you don't have an explosive xⁿ.
Also, but that is an optimization, you don't really need to compute neither (-1)ⁿ with pow (just alternate a int sign variable, between -1 and 1 at each iteration), nor x²ⁿ (just multiply a double x2n=1 by x*x each iteration), nor fac(2n) (just multiply a f=1 variable by (n-1)×n, being careful with 0 case, at each iteration.
Related
This is my homework:
I haven't tried to write the part of Natural Logarithm because I can't solve the part of Exponential.
This is the the approximations of Exponential in C using Taylor Series expansion I wrote.
However, it returns inf. What did I do wrong?
#include <stdio.h>
// Returns approximate value of e^x
// using sum of first n terms of Taylor Series
float exponential(int n, float x)
{
float sum = 1.0f; // initialize sum of series
for (int a = n; a >= 0; ++a ) {
while (x * sum / a < 0.00001) {
break;
}
sum = 1 + x * sum / a;
return sum;
}
}
int main()
{
int n = 0;
float x = 1.0f;
printf("e^x = %.5f", exponential(n, x));
return 0;
}
With How do I ask and answer homework questions? in mind, I will give you a few things to have a careful look at.
From comment by Spektre:
from a quick look you are dividing by zero in while (x * sum / a < 0.00001) during first iteration of for loop as a=n and you called the function with n=0 ... also your code does not match the expansion for e^x at all
Have a look at the for loop:
for (int a = n; a >= 0; ++a )
What is the first value of a? The second? The third?
Keep in mind that the values are determined by ++a.
When will that loop end? It is determined by a >= 0. When is that false?
What is this loop doing?
while (x * sum / a < 0.00001) {
break;
}
I suspect that you programmed "English to C", as "do the outer loop while ...", which is practically from the assignment.
But the loop does something else. Apart from risking the division by 0 mentioned above, if the condition is true it will stay true and cause an endless loop, which then however is immediatly canceled in the first iteration.
The head of your function float exponential(int n, float x) expects n as a parameter. In main you init it with 0. I suspect you are unclear about where that value n is supposed to come from. In fact it is unknown. It is more a result of the calculation than an input.
You are supposed to add up until something happens.
You do not actually ever need the value of n. This means that your for loop is meaningless. The inner loop (though currently pointless) is much closer to your goal.
I will leave it at this for now. Try to use this input.
Feel free to edit the code in your question with improvements.
(Normally that is not appreciated, but in case of homework dialog questions I am fine with it.)
Your current implementation attempt is quite a bit off. Therefore I will describe how you should approach calculating such a series as given in your quesiton.
Let's look at your first formula:
You need to sum up terms e(n) = x^n / n!
To check with your series: 1 == x^0 / 0! - x == x^1 / 1! - ...
To calculate these terms, you need a simple rule how to get from e(n) to e(n+1). Looking at the formula above we see that you can use this rule:
e(n+1) = e(n) * x / (n+1)
Then you need to create a loop around that and sum up all the bits & pieces.
You are clearly not supposed to calculate x^n/n! from scratch in each iteration.
Your condition to stop the loop is when you reach the limit of 1e-5. The limit is for the new e(n+1), not for the sum.
For the other formulas you can use the same approach to find a rule how to calculate the single terms.
You might need to multiply the value by -1 in each step or do something like *x*n/(n+1) instead of *x/(n+1) etc.
Maybe you need to add some check if the formula is supposed to converge. Then maybe print some error message. This part is not clear in your question.
As this is homework, I only point into the direction and leave the implementation work to you.
If you have problems with implementation, I suggest to create a new question.
#include <stdio.h>
int main() {
float power;
printf("Enter the power of e\n");
scanf("%f", &power);
float ans = 1;
float temp = 1;
int i = 1;
while ((temp * power) / i >= 0.00001) {
temp = (temp * power) / i;
ans = ans + temp;
i++;
}
printf("%.5f", ans);
return 0;
}
I think I solved the problem
But the part about Natural Log is not solved, I will try.
Check the image
This is my 1st post so have that in mind while reading my question.
I have an exam of a colloquium but my code does not provide me the correct result.
So if anyone could help me that would be great. :)
These are the informations that are provided in the exam:
A function y=f(x)=ax^2+bx+c
We have to find the surface that is below the chart but keep in mind that dx(Delta X)=B-A and the height goes like this: A,A+dx,A+2dx, .... , B-dx.
As dx value gets lower the surface will be more accurate.
You have to write the program so that the surface with precision 0.001
This is my code so could someone who is good in C check it please.
Thank you.
#include <stdio.h>
#include <math.h>
int main()
{
int a,b,c;
double A,B,dx,p,D,q,x,y,nv,nv1,nv2,sv;
do{
printf("Insert a & b: "),scanf("%lf %lf",&A,&B);
} while(A<1 || B<1);
nv=dx=B-A;
do{
printf("enter odds: "),scanf("%d %d %d",&a,&b,&c);
p=(-b)/2;
D=sqrt(pow(b,2)-4*a*c);
q= -D/4*a;
} while( a<0 || p<0 || q<0);
do{
sv=nv;
dx/=2;
nv=0;
for(x=A;x<p;x+=dx)
for(dx=B-A;dx<q;dx/=2)
nv1+=x*dx;
for(y=p;y<=B;y+=dx)
for(dx=q;dx<B;dx/=2)
nv2+=y*dx;
nv=nv1+nv2;
}while(fabs(nv-sv)>0.001);
printf("The surface is %lf",nv);
return 0;
}
You want to find the approximation of a definite integral of a quadratic function. There are several issues with your code:
What is the restriction of A ≥ 1 and B ≥ 1 for? A parabola is defined over the whole abscissa. If anything, you should enforce that the input is numeric and that two values were given.
You don't need to find the vertex of the parabola. Your task is to create small rectangles based on the left x value of each interval as the image shows. Therefore, you don't need p and q. And you shouldn't enforce that the vertex is in the first quadrant on the input without indication.
Why are the coefficients of the parabola integers? Make them doubles to be consistent.
Because you don't need to know the vertex, you don't need to split your loop in two. In your code, you don't even check that p is between A and B, which is a requirement of cour code.
What is the inner loop for? You are supposed to just calculate the area of the current rectangle here. What's worse: you re-use the variable dx as iteration variable, which means you lose it as an indicator of how large your current interval is.
The repeated incrementing of dx may lead to an accumulated floating-point error when the number of intervals is large. A common technique to avoid this is to use an integer variable for loop control and the determine the actual floating-point variable by multiplication.
The absolute value as a convergence criterion may lead to problems with small and big numbers. The iteration ends too early for small values and it may never reach the criterion for big numbers, where a difference of 0.001 cannot be resolved.
Here's a version of your code that puts all that into practice:
#include <stdio.h>
#include <math.h>
int main()
{
double a, b, c;
double A, B;
printf("Lower and upper limit A, B: ");
scanf("%lf %lf", &A, &B);
printf("enter coefficients a, b, c: ");
scanf("%lf %lf %lf", &a, &b, &c);
double nv = 0;
double sv;
int n = 1;
do {
int i;
double dx;
sv = nv;
n *= 2;
dx = (B - A) / n;
nv = 0;
for (i = 0; i < n; i++) {
double x = A + i * (B - A) / n;
double y = a*x*x + b*x + c;
nv += dx * y;
}
} while(fabs(nv - sv) > 0.0005 * fabs(nv + sv));
printf("Surface: %lf\n", nv);
return 0;
}
The code is well-behaved for empty intervals (where A = B) or reversed intervals (where A > B). The inpt is still quick and dirty. It should really heck that the entered values are valid numbers. There's no need to restrict the input arbitrarily, though.
I am pretty flabbergasted as to why my code got stuck at the 16512th iteration even though it seemed to have no syntactical problems. Here is the code:
#include <stdio.h>
/*C version of Newton-Raphson method*/
float sqrt(float num);
main()
{
int i;
for (i = 1; i <= 100000; i++) {
printf("%d: %.3f\n", i, sqrt(i));
}
}
float sqrt(float num)
{
float guess, e, upperbound;
guess = 1;
e = 0.001;
do
{
upperbound = num / guess;
guess = (upperbound + guess) / 2;
} while (!(guess * guess >= num - e &&
guess * guess <= num + e));
return guess;
}
The code is supposed to find the square-root of all numbers from 1 to 100000 using the Newtonian-Raphson method, but nothing happened after the 16152th iteration. I am using the Developer Command Prompt for VS2012 to compile my scripts, if that information is of any help. Enlightenment will be gladly appreciated.
Honestly, when I posted mycomment, it was more a hunch than real knowledge. The algorithm was valid, so something must be making the while loop not terminate, and since you were properly using epsilons, we were hitting the limits from the float.
#PaulR's comments make it make more sense. The sqrt of 16512 is 128.499027233672... Float has fairly limited precision, so it wasn't getting anything within .001 of that number. It makes even more sense if you think of an even bigger number, e.g. sqrt(123455555.54321) (which is 11111.11111). Floating point precision won't necessarily even get you to the 11111, let alone 11111.111.
Changing to double "fixes" this, but just kicks the can down the road. Somewhere later on, we'd have the same precision issue, and this algorithm should work on any size number.
#mrbratch brings up the robust solution - define your tolerance as a percentage of the number. If you set e = num * 0.00001, your loop will always complete. Obviously, you can play with epsilon and tweak it to your satisfaction. And note, for big numbers, this can give you an integer that's not even the closest int to the right answer.
I can't speak for python, but I can confirm that javascript uses double precision.
As already explained in the comments, the problem is because you can't have that much precision (0.001) with any number. In particular, when the number is large enough, only the most important digits are saved. See the IEEE 754 standard if you want more information about how it works. http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
Now, I'd recommend that you use a percentage of error for the tolerance:
float sqrt(float num)
{
float guess, e, upperbound;
guess = 1;
e = 0.001;
do
{
upperbound = num / guess;
guess = (upperbound + guess) / 2;
} while (!(guess * guess / num >= 1 - e &&
guess * guess / num <= 1 + e));
return guess;
}
Simple adjustment
Use relative Floating Point precision, not absolute.
There area as many FP representable numbers between 0.001 and 0.002 as between 1,000 and 2,000. So when calculating square root, the iterations should depend on the local relative error.
Do not use absolute error bounds like e = 0.001, but relative ones. Code then runs just fine.
// e = 0.001;
e = 0.001 * num;
[edit] I know see #Scott Mermelstein has a similar comment.
IMHO, the squaring causes loss of precision:
#include <stdio.h>
/*C version of Newton-Raphson method*/
float mysqrt(float num); /* avoid conflicts with built-in sqrt() if any */
int main(void)
{
int i;
for (i = 1; i <= 100000; i++) {
printf("%d: %.3f\n", i, (double)mysqrt(i)); /* cast to double, since printf() is varargs */
}
return 0;
}
float mysqrt(float num)
{
float newguess, e, oldguess;
e = 0.001;
newguess = 1.0;
do
{
oldguess = newguess;
newguess = (num/oldguess + newguess ) / 2;
/* compare tor the previous value; avoid squaring */
} while (newguess / oldguess > (1+e) || oldguess / newguess > (1+e) );
// } while (newguess < oldguess -e || newguess > oldguess +e); // "mostly works"
return newguess;
}
I'm new to the C language and am trying to do a lab tutorial that we were given at uni.
We've been asked to do the following:
Task 1.
The Babylonian algorithm to compute the square root of a number n is as follows:
1. Make a guess at the answer (you can pick n/2 as your initial guess).
Compute r = n / guess
Set guess = (guess +r) / 2
Go back to step 2 for as many iterations as necessary. The more that steps 2 and 3 are
repeated, the closer guess will become to the square root of n.
Write a program that inputs an integer for n, iterates through the Babylonian algorithm
five times, and outputs the answer as a double to two decimal places. Your answer will
be most accurate for small values of n.
Here is what I have written:
#include <stdio.h>
#include <math.h>
int n;
main(void){
printf("Enter a value for n: ");
scanf("%d",&n);
double guess = n / 2;
for (int i = 0; i < 5; i++) {
double r = n / guess;
double guess = (guess + r) / 2;
}
printf("%d",guess);
}
Where have I gone wrong? It spits out ridiculous results; for example if I input "4" as n, the answer should be around "2", but it gives different huge results each time.
Another solution would be:
guess = guess / 2.0;
This would "force" a floating-point operation.
And the variable guess is already in the scope. You can´t redeclare it (as you did inside the loop). You can only set it a new value.
And you also need to change the printf to :
printf("%f",guess);
Check this link for more info about the printf formatters:
http://www.cplusplus.com/reference/cstdio/printf/
A few things wrong here.
First, you have scoped a second instance of guess inside the loop. Take away the double declaration on that line. So it should become:
guess = (guess + r) / 2;
Second, because guess is a double you need to use %f instead of %d in the printf call.
printf( "%f", guess );
Once you get it working, consider running the algorithm until a certain accuracy is achieved.
const double epsilon = 0.0001;
double guess = (double)n / 2.0;
double r = 0.0;
while( fabs(guess * guess - (double)n) > epsilon )
{
r = (double)n / guess;
guess = (guess + r) / 2.0;
}
The Babylonian Algorithm seems incorrect to me, it should be like this,
int i;
float n,guess=1;
printf("\nEnter the Number: ");
scanf("%f",&n);
for(i=0;i<PRECISION;i++)
{
guess=(guess+n/guess)/2;
}
printf("\nThe Square root of %f is %f",n,guess);
There are other possible errors also in your program,
There might be the problem of integer division,
The line double guess = n / 2;
should be double guess = (double) n / 2;
Also the printf() should be printf("%lf",guess);
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Using two functions:
Factorial Function
Power Function
Develop a C program for the following equation:
I've done this . but no output.
#include <stdio.h>
#include <math.h>
double factorial(double x);
double Power_function(double y);
int main(){
double answer=0;
double n;
double y;
printf("Enter Y :The last limit of the summation:>");
scanf("%ld",&y);
for (n=1;n<=y;++n){
answer=answer +factorial(n)*Power_function(n)*y;
}
printf("The Answer is %0.2f\n",answer);
return 0;
}
double factorial(double x)
{
double ans;
if (x==0){
ans = 1;
}
else
{
ans = x*factorial(x-1);
}
return ans;
}
double Power_function(double y){
double ans;
ans=pow(2,y);
return ans;
}
I've a suspicion what one of the learning outcomes of this is and too much help here will give the game away.
I think i can safely say you need to break each part of the equation down to smaller solvable parts.
The three biggest parts are summation, N Factorial (N!) and 2 to the power N
The summation is effectively a loop with N starting at 1 and ending at y, so look for the C syntax to write a loop (hint there are two common types, while and for)
The other two are functions, if your allowed to use premade functions then plenty exist only a google away which will sort you out nicely, if not you'll have to write your own.
factorial is n*(n-1)*(n-2)...(n-(n-2))*(n-(n-1))
so 4! = 4*3*2*1
a prime candidate for a recursive function or a function with a descending loop in it
2 to the power n is 2 multiplied by itself n times
so 2 to the power 2 = 2*2
2 to the power 3 = 2*2*2 and so on
Once again a loop looks like a good place to start with that.
After that its just a matter of using your two functions inside the loop, giving the user a way to input Y and testing with some numbers.
1,2,3 would be a good start as they're nice and easy to work out on a calculator.
All well and good so far I'd hope, -1 should make interesting things happen to every example I've seen posted so far, and that's before we start pushing the boat out with big numbers like 32.
Edit:
Right, I've taken a look at your code, and it looks like your problem isn't in the implementation of your algorithm, its not reading the variable in correctly, outputing y just after you set it yields 0, so something isn't working quite right there. Im not a c coder but i had a quick hack at it with some liberal googling and your non functional code and made it read an argument in then parse it to a double.
#include<stdio.h>
#include<math.h>
double factorial(double x);
double Power_function(double y);
main(int argc, char *argv[]){
double answer=0;
double n;
double y;
y = atol(argv[1]);
//printf("%lf\n",y);
for (n=1;n<=y;++n){
answer=answer +factorial(n)*Power_function(n)*y;
}
printf("The Answer is %0.2f\n",answer);
return 0;
}
double factorial(double x)
{
double ans;
if (x==0){
ans = 1;
}
else
{
ans = x*factorial(x-1);
}
return ans;
}
double Power_function(double y){
double ans;
ans=pow(2,y);
return ans;
}
So essentially your code with a different input method,
compiled using
gcc so.c -lm
executed as
./a.out 1
yields The Answer is 2.00
./a.out 2
yields The Answer is 20.00
./a.out 3
yields The Answer is 174.00
Pen and paper maths backs it up so your algorithm is sound so far!
Feed it some negative numbers and some huge numbers to see what it does from here!
I didn't do everything for you, but here is a basic outline.
You must finish it off.
int answer = 0;
int n;
for(n=1; n <= y; ++n)
{
answer = answer + (n! * 2^n)*y;
}
You're looking for the sum of (n! * 2^n) from 1 to y.
total variable is 0
for 1 until y:
multiply factorial(n) and pow(2, n) and add this to total
end of loop
print out total
First thing to do is to write down what you manually would do to work that equation out. Try out 1 to 5, for example, and see what you get.