Example of a colloquium exam - c

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.

Related

Calculate cosine in C

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.

Need help solving a problem with an array

Task: Calculate the 25 values of the function y = ax'2 + bx + c on the interval [e, f], save them in the array Y and find the minimum and maximum values in this array.
#include <stdio.h>
#include <math.h>
int main()
{
float Y[25];
int i;
int x=3,a,b,c;
double y = a*pow(x,2)+b*x+c;
printf("a = ", b);
scanf("%d", &a);
printf("b = ", a);
scanf("%d", &b);
printf("c = ", c);
scanf("%d", &c);
for(i=0;i<25;i++)
{
printf("%f",y); //output results, not needed
x++;
}
system("pause");
}
Problems:
Cant understand how can I use "interval [e,f]" here
Cant understand how to save values to array using C libraries
Cant understand how to write/make a cycle, which will find the
minimum and maximum values
Finally, dont know what exactly i need to do to solve task
You must first ask the user for the values of a, b, c or initialize those variables, and ask for the interval values of e, f, or initialize those variables.
Now you must calculate double interval= (f - e)/25.0 so you have the interval.
Then you must have a loop for (int i=0, double x=e; i<25; i++, x += interval) and calculate each value of the function. You can choose to store the result in an array (declare one at the top) or print them directly.
Problems:
Cant understand how can I use "interval [e,f]" here
(f-e) / 25(interval steps)
Cant understand how to save values to array using C libraries
You need to use some form of loop to traverse the array and save the result of your calculation at every interval step. Something like this:
for(int i = 0; i < SIZE; i++)
// SIZE in this case 25, so you traverse from 0-24 since arrays start 0
Cant understand how to write/make a cycle, which will find the minimum and maximum values
For both cases:
traverse the array with some form of loop and check every item e.g. (again) something like this: for(int i = 0; i < SIZE; i++)
For min:
Initialize a double value(key) with the first element of your array
Loop through your array searching for elements smaller than your initial key value.
if your array at position i is smaller than key, save key = array[i];
For max:
Initialize a double value(key) with 0;
Loop through your array searching for elements bigger than your initial key value.
if your array at position i is bigger than key, save key = array[i];
Finally, dont know what exactly i need to do to solve task
Initialize your variables(yourself or through user input)
Create a function that calculates a*x^2 + b*x + c n times for every step of your interval.
Create a function for min & max that loops through your array and returns the smallest/biggest value.
Thats pretty much it. I will refrain from posting code(for now), since this looks like an assignment to me and I am confident that you can write the code with the information #Paul Ogilvie & I have provided yourself. Good Luck
#include<stdio.h>
#include<math.h>
int main()
{
double y[25];
double x,a,b,c,e,f;
int i,j=0;
printf("Enter a:",&a);
scanf("%lf",&a);
printf("Enter b:",&b);
scanf("%lf",&b);
printf("Enter c:",&c);
scanf("%lf",&c);
printf("Starting Range:",&e);
scanf("%lf",&e);
printf("Ending Range:",&f);
scanf("%lf",&f);
for(i=e;i<=f;i++)
{
y[j++]=(a*pow(i,2))+(b*i)+c;
}
printf("\nThe Maximum element in the given interval is %lf",y[j-1]);
printf("\nThe Minimum element in the given interval is %lf",y[0]);
}
Good LUCK!

Basic C Program, Babylonian Algorithm

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);

How to Approximate e in an Infinite Series in C

So I am trying to do this problem:
However, I'm not entirely sure where to start or what exactly I am looking for.
In addition, I was told I should expect to give the program inputs such as: zero (0), very small (0.00001), and not so small (0.1).
I was given this: http://en.wikipedia.org/wiki/E_%28mathematical_constant%29 as a reference, but that formula doesn't look exactly like the one in the problem.
And finally, I was told that the input to the program is a small number Epsilon. You may assume 0.00001f, for example.
You keep adding the infinite series until the current term's value is below the Epsilon.
But all in all, I have no clue what that means. I somewhat understand the equation on the wiki. However, I'm not sure where to start with the problem given. Looking at it, does anyone know what kind of formula I should be looking to use in C and what "E" is and where it comes into play here (i.e. within the formula, I understand it's suppose to be the user input).
Code So Far
#include <stdio.h>
#include <math.h>
//Program that takes in multiple dates and determines the earliest one
int main(void)
{
float e = 0;
float s = 0;
float ct = 1;
float ot= 1;
int n = 0;
float i = 0;
float den = 0;
int count = 0;
printf("Enter a value for E: ");
scanf("%f", &e);
printf("The value of e is: %f", e);
for(n = 0; ct > e; n++)
{
count++;
printf("The value of the current term is: %f", ct);
printf("In here %d\n", count);
den = 0;
for(i = n; i > 0; i--)
{
den *= i;
}
//If the old term is one (meaning the very first term), then just set that to the current term
if (ot= 1)
{
ct = ot - (1.0/den);
}
//If n is even, add the term as per the rules of the formula
else if (n%2 == 0)
{
ct = ot + (1.0/den);
ot = ct;
}
//Else if n is odd, subtract the term as per the rules of the formula
else
{
ct = ot - (1.0/den);
ot = ct;
}
//If the current term becomes less than epsilon (the user input), printout the value and break from the loop
if (ct < epsilon)
{
printf("%f is less than %f",ct ,e);
break;
}
}
return 0;
}
Current Output
Enter a value for E: .00001
The value of e is: 0.000010
The value of the current term is: 1.000000
In here 1
-1.#INF00 is less than 0.000010
So based on everyone's comments, and using the 4th "Derangements" equation from wikipedia like I was told, this is the code I've come up with. The logic in my head seems to be in line with what everyone has been saying. But the output is not at all what I am trying to achieve. Does anyone have any idea from looking at this code what I might be doing wrong?
Σ represents a sum, so your equation means to compute the sum of the terms starting at n=0 and going towards infinity:
The notation n! means "factorial" which is a product of the numbers one through n:
Each iteration computed more accurately represents the actual value. ε is an error term meaning that the iteration is changing by less than the ε amount.
To start computing an interation you need some starting conditions:
unsigned int n = 0; // Iteration. Start with n=0;
double fact = 1; // 0! = 1. Keep running product of iteration numbers for factorial.
double sum = 0; // Starting summation. Keep a running sum of terms.
double last; // Sum of previous iteration for computing e
double e; // epsilon value for deciding when done.
Then the algorithm is straightforward:
Store the previous sum.
Compute the next sum.
Update n and compute the next factorial.
Check if the difference in the new vs. old iteration exceeds epsilon.
The code:
do {
last = sum;
sum += 1/fact;
fact *= ++n;
} while(sum-last >= e);
You need to write a beginning C program. There are lots of sources on the interwebs for that, including how to get user input from the argc and argv variables. It looks like you are to use 0.00001f for epsilon if it is not entered. (Use that to get the program working before trying to get it to accept input.)
For computing the series, you will use a loop and some variables: sum, current_term, and n. In each loop iteration, compute the current_term using n, increment n, check if the current term is less than epsilon, and if not add the current_term to the sum.
The big pitfall to avoid here is computing integer division by mistake. For example, you will want to avoid expressions like 1/n. If you are going to use such an expression, use 1.0/n instead.
Well in fact this program is very similar to the ones given in the learning to Program in C by Deitel, well now to the point (the error can't be 0 cause e is a irrational number so it can't be calculated exactly) I have here a code that may be very useful for you.
#include <stdio.h>
/* Function Prototypes*/
long double eulerCalculator( float error, signed long int *iterations );
signed long int factorial( int j );
/* The main body of the program */
int main( void )
{
/*Variable declaration*/
float error;
signed long int iterations = 1;
printf( "Max Epsilon admited: " );
scanf( "%f", &error );
printf( "\n The Euler calculated is: %f\n", eulerCalculator( error, &iterations ) );
printf( "\n The last calculated fraction is: %f\n", factorial( iterations ) );
return 1;
}
long double eulerCalculator( float error, signed long int *iterations )
{
/* We declare the variables*/
long double n, ecalc;
/* We initialize result and e constant*/
ecalc = 1;
/* While the error is higher than than the calcualted different keep the loop */
do {
n = ( ( long double ) ( 1.0 / factorial( *iterations ) ) );
ecalc += n;
++*iterations;
} while ( error < n );
return ecalc;
}
signed long int factorial( signed long int j )
{
signed long int b = j - 1;
for (; b > 1; b--){
j *= b;
}
return j;
}
That summation symbol gives you a clue: you need a loop.
What's 0!? 1, of course. So your starting value for e is 1.
Next you'll write a loop for n from 1 to some larger value (infinity might suggest a while loop) where you calculate each successive term, see if its size exceeds your epsilon, and add it to the sum for e.
When your terms get smaller than your epsilon, stop the loop.
Don't worry about user input for now. Get your function working. Hard code an epsilon and see what happens when you change it. Leave the input for the last bit.
You'll need a good factorial function. (Not true - thanks to Mat for reminding me.)
Did you ask where the constant e comes from? And the series? The series is the Taylor series expansion for the exponential function. See any intro calculus text. And the constant e is simple the exponential function with exponent 1.
I've got a nice Java version working here, but I'm going to refrain from posting it. It looks just like the C function will, so I don't want to give it away.
UPDATE: Since you've shown yours, I'll show you mine:
package cruft;
/**
* MathConstant uses infinite series to calculate constants (e.g. Euler)
* #author Michael
* #link
* #since 10/7/12 12:24 PM
*/
public class MathConstant {
public static void main(String[] args) {
double epsilon = 1.0e-25;
System.out.println(String.format("e = %40.35f", e(epsilon)));
}
// value should be 2.71828182845904523536028747135266249775724709369995
// e = 2.718281828459045
public static double e(double epsilon) {
double euler = 1.0;
double term = 1.0;
int n = 1;
while (term > epsilon) {
term /= n++;
euler += term;
}
return euler;
}
}
But if you ever need a factorial function I'd recommend a table, memoization, and the gamma function over the naive student implementation. Google for those if you don't know what those are. Good luck.
Write a MAIN function and a FUNCTION to compute the approximate sum of the below series.
(n!)/(2n+1)! (from n=1 to infinity)
Within the MAIN function:
Read a variable EPSILON of type DOUBLE (desired accuracy) from
the standard input.
EPSILON is an extremely small positive number which is less than or equal to
to 10^(-6).
EPSILON value will be passed to the FUNCTION as an argument.
Within the FUNCTION:
In a do-while loop:
Continue adding up the terms until |Sn+1 - Sn| < EPSILON.
Sn is the sum of the first n-terms.
Sn+1 is the sum of the first (n+1)-terms.
When the desired accuracy EPSILON is reached print the SUM and the number
of TERMS added to the sum.
TEST the program with different EPSILON values (from 10^(-6) to 10^(-12))
one at a time.

Program that calculates area between quadratic and x-axis in C

I'm new to this whole programming things so bear with me.
I want to make a program that could calculat the area between quadratic and x-axis.
Right now my code is only designed for functions were a is postive and c is negative.
#include <stdio.h>
int main()
{
float a;
float b;
float c;
float x; /* this is the zero that is to the right*/
float y; /* this is the zero that is to the left*/
float z;
{
printf("Consider the function ax^2 + bx + c\n");
printf("Enter the a value: \n");
scanf("%f",&a);
printf("Enter the b value: \n");
scanf("%f",&b);
printf("Enter the c value: \n");
scanf("%f", &c);
x = (( -b + sqrt(b*b - 4*a*c)) / (2*a));
y = (( -b - sqrt(b*b - 4*a*c)) / (2*a));
do {
z=(((y+0.01)-(y))*((a*(y*y))+(b*y)+(c)));
y+0.01;} while (x>y);
if (y>=x) {
printf("The area is %f", z);
}
The problem is that the program just never stops running. What im trying to do is to make small squares and measure their area (remmember LRAM and RRAM). So what im doing is (zero + a little bit) times y value (a*(y*y))+(b*y)+(c)))`
Any tips?
In
do {
z=(((y+0.01)-(y))*((a*(y*y))+(b*y)+(c)));
y+0.01;
} while (x>y);
you should change y+0.01 to y += 0.01, if you use y+0.01, y never change during the loop.
Increment both z and y in the do while loop.
z = 0; //initialize z to remove any garbage values.
do {
// here z is NOT getting assigned, but incremented each time this loop runs.
// NOTE: A += C; is short for A = A + C;
z += (((y+0.01)-(y))*((a*(y*y))+(b*y)+(c)));
y += 0.01;
}
while (x>y);
I understand it doesn't help immediately, but for stuff like this, Numerical Recipes is the ultimate book. The old C version (which of course, still works quite nicely in C++) is available for free. They also have a C++ version you can buy.
It has code for every algorithm in the book, and explains step by step what you are doing and why.
Link to homepage
Link to C version

Resources