Having trouble with pow() in C - c

I am currently reading an online version of Stephen Kochan's "Programming in C (3rd Edition)." One of the activities involves evaluating an equation,
Write a program that evaluates the following expression and displays the results
(remember to use exponential format to display the result):
(3.31 x 10-8 x 2.01 x 10-7) / (7.16 x 10-6 + 2.01 x 10-8)
When I attempt to do this, the output is always 0.0000. Here is my code.
#include <stdio.h>
int main (void) {
float result;
result = (3.31 * pow(10,-8) * 2.01 * pow(10,-7)) / (7.16 * pow(10,-6) + 2.01 * pow(10, -8));
printf ("%f", result);
return 0;
}
If I am doing anything wrong, please point it out. If you have any tips, please say so.

You must #include <math.h>
Also, change to this:
printf ("%e\n", result);
You should probably also have
double result;
because pow() returns a double.

Use %e to get an exponent result value as instructed.
int main (void)
{
float i;
float j;
float result;
result = i / j;
i = 3.31 * 10 -8 * 2.01 * 10 -7;
j = 7.16 * 10 -6 + 2.01 * 10 -8;
printf("%e", i, j, result);
return 0;
}

Related

Function that implements Taylor Series in C return the value of the argument

I was experimenting with the Taylor Series expansion for tan(x) in C. I've created a super simple function whose purpose is to return the answer of the expansion (see code below). The issue is that when one invokes it, the answer is the argument of the tangent, i.e. if you call the function tangent as tangent(0.7853981634), which is pi/4 btw, you get that same number 0.7853981634.
#include <stdio.h>
float power(float x, int pow);
float tangent(float x);
void main(){
float ans;
ans = tangent(0.7853981634);
printf("La tangente da %f \n", ans);
}
float tangent(float x){
return x + 1/3 * (x * x * x) + 2/15 * (x * x * x * x * x);
}
NOTE: I know that there are plenty of things to improve, it's just that I don't know why this code does not work properly.

Using a Taylor series to find sin(x) in 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.

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

Numerical Integral from 0 to infinity

My aim is to calculate the numerical integral of a probability distribution function (PDF) of the distance of an electron from the nucleus of the hydrogen atom in C programming language. I have written a sample code however it fails to find the numerical value correctly due to the fact that I cannot increase the limit as much as its necessary in my opinion. I have also included the library but I cannot use the values stated in the following post as integral boundaries: min and max value of data type in C . What is the remedy in this case? Should switch to another programming language maybe? Any help and suggestion is appreciated, thanks in advance.
Edit: After some value I get the error segmentation fault. I have checked the actual result of the integral to be 0.0372193 with Wolframalpha. In addition to this if I increment k in smaller amounts I get zero as a result that is why I defined r[k]=k, I know it should be smaller for increased precision.
#include <stdio.h>
#include <math.h>
#include <limits.h>
#define a0 0.53
int N = 200000;
// This value of N is the highest possible number in long double
// data format. Change its value to adjust the precision of integration
// and computation time.
// The discrete integral may be defined as follows:
long double trapezoid(long double x[], long double f[]) {
int i;
long double dx = x[1]-x[0];
long double sum = 0.5*(f[0]+f[N]);
for (i = 1; i < N; i++)
sum+=f[i];
return sum*dx;
}
main() {
long double P[N], r[N], a;
// Declare and initialize the loop variable
int k = 0;
for (k = 0; k < N; k++)
{
r[k] = k ;
P[k] = r[k] * r[k] * exp( -2*r[k] / a0);
//printf("%.20Lf \n", r[k]);
//printf("%.20Lf \n", P[k]);
}
a = trapezoid(r, P);
printf("%.20Lf \n", a);
}
Last Code:
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#define a0 0.53
#define N LLONG_MAX
// This value of N is the highest possible number in long double
// data format. Change its value to adjust the precision of integration
// and computation time.
// The discrete integral may be defined as follows:
long double trapezoid(long double x[],long double f[]) {
int i;
long double dx = x[1]-x[0];
long double sum = 0.5*(f[0]+f[N]);
for (i = 1; i < N; i++)
sum+=f[i];
return sum*dx;
}
main() {
printf("%Ld", LLONG_MAX);
long double * P = malloc(N * sizeof(long double));
long double * r = malloc(N * sizeof(long double));
// Declare and initialize the loop variable
int k = 0;
long double integral;
for (k = 1; k < N; k++)
{
P[k] = r[k] * r[k] * expl( -2*r[k] / a0);
}
integral = trapezoid(r, P);
printf("%Lf", integral);
}
Edit last code working:
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#define a0 0.53
#define N LONG_MAX/100
// This value of N is the highest possible number in long double
// data format. Change its value to adjust the precision of integration
// and computation time.
// The discrete integral may be defined as follows:
long double trapezoid(long double x[],long double f[]) {
int i;
long double dx = x[1]-x[0];
long double sum = 0.5*(f[0]+f[N]);
for (i = 1; i < N; i++)
sum+=f[i];
return sum*dx;
}
main() {
printf("%Ld \n", LLONG_MAX);
long double * P = malloc(N * sizeof(long double));
long double * r = malloc(N * sizeof(long double));
// Declare and initialize the loop variable
int k = 0;
long double integral;
for (k = 1; k < N; k++)
{
r[k] = k / 100000.0;
P[k] = r[k] * r[k] * expl( -2*r[k] / a0);
}
integral = trapezoid(r, P);
printf("%.15Lf \n", integral);
free((void *)P);
free((void *)r);
}
In particular I have changed the definition for r[k] by using a floating point number in the division operation to get a long double as a result and also as I have stated in my last comment I cannot go for Ns larger than LONG_MAX/100 and I think I should investigate the code and malloc further to get the issue. I have found the exact value that is obtained analytically by taking the limits; I have confirmed the result with TI-89 Titanium and Wolframalpha (both numerically and analytically) apart from doing it myself. The trapezoid rule worked out pretty well when the interval size has been decreased. Many thanks for all the posters here for their ideas. Having a value of 2147483647 LONG_MAX is not that particularly large as I expected by the way, should the limit not be around ten to power 308?
Numerical point of view
The usual trapezoid method doesn't work with improper integrals. As such, Gaussian quadrature rules are much better, since they not only provide 2n-1 exactness (that is, for a polynomial of degree 2n-1 they will return the correct solution), but also manage improper integrals by using the right weight function.
If your integral is improper in both sides, you should try the Gauss-Hermite quadrature, otherwise use the Gauss-Laguerre quadrature.
The "overflow" error
long double P[N], r[N], a;
P has a size of roughly 3MB, and so does r. That's too much memory. Allocate the memory instead:
long double * P = malloc(N * sizeof(long double));
long double * r = malloc(N * sizeof(long double));
Don't forget to include <stdlib.h> and use free on both P and r if you don't need them any longer. Also, you may not access the N-th entry, so f[N] is wrong.
Using Gauss-Laguerre quadrature
Now Gauss-Laguerre uses exp(-x) as weight function. If you're not familiar with Gaussian quadrature: the result of E(f) is the integral of w * f, where w is the weight function.
Your f looks like this, and:
f x = x^2 * exp (-2 * x / a)
Wait a minute. f already contains exp(-term), so we can substitute x with t = x * a /2 and get
f' x = (t * a/2)^2 * exp(-t) * a/2
Since exp(-t) is already part of our weight function, your function fits now perfectly into the Gauss-Laguerre quadrature. The resulting code is
#include <stdio.h>
#include <math.h>
/* x[] and a[] taken from
* https://de.wikipedia.org/wiki/Gau%C3%9F-Quadratur#Gau.C3.9F-Laguerre-Integration
* Calculating them by hand is a little bit cumbersome
*/
const int gauss_rule_length = 3;
const double gauss_x[] = {0.415774556783, 2.29428036028, 6.28994508294};
const double gauss_a[] = {0.711093009929, 0.278517733569, 0.0103892565016};
double f(double x){
return x *.53/2 * x *.53/2 * .53/2;
}
int main(){
int i;
double sum = 0;
for(i = 0; i < gauss_rule_length; ++i){
sum += gauss_a[i] * f(gauss_x[i]);
}
printf("%.10lf\n",sum); /* 0.0372192500 */
return 0;
}

How to get fractions in an integer division?

How do you divide two integers and get a double or float answer in C?
You need to cast one or the other to a float or double.
int x = 1;
int y = 3;
// Before
x / y; // (0!)
// After
((double)x) / y; // (0.33333...)
x / ((double)y); // (0.33333...)
Of course, make sure that you are store the result of the division in a double or float! It doesn't do you any good if you store the result in another int.
Regarding #Chad's comment ("[tailsPerField setIntValue:tailsPer]"):
Don't pass a double or float to setIntValue when you have setDoubleValue, etc. available. That's probably the same issue as I mentioned in the comment, where you aren't using an explicit cast, and you're getting an invalid value because a double is being read as an int.
For example, on my system, the file:
#include <stdio.h>
int main()
{
double x = 3.14;
printf("%d", x);
return 0;
}
outputs:
1374389535
because the double was attempted to be read as an int.
Use type-casting.
For example,
main()
{
float a;
int b = 2, c = 3;
a = (float) b / (float) c; // This is type-casting
printf("%f", a);
}

Resources