Calculating $\sqrt[3]{x}$ with Babylonian method - c

Consider my attempt to implement the Babylonian method in C:
int sqrt3(int x) {
double abs_err = 1.0;
double xold = x;
double xnew = 0;
while(abs_err > 1e-8) {
xnew = (2 * xold + x/(xold* xold))/3;
abs_err= xnew-xold;
if (abs_err < 0) abs_err = -abs_err;
xold=xnew;
}
return xnew;
}
int main() {
int a;
scanf("%d", &a);
printf(" Result is: %f",sqrt3(a));
return 0;
}
Result is for x=27: 0.0000?
Where is my mistake?

While the function returns an int, that value is printed with the wrong format specifier, %f instead of %d.
Change the signature (and the name, if I may) into something like this
double cube_root(double x) { ... }
Or change the format specifier, if you really want an int.

Following the explanation from tutorialspoint, which states, that the basic idea is to implement the Newton Raphson method for solving nonlinear equations, IMHO, the code below displays this fact more clearly. Since there is already an accepted answer, I add this answer just for future reference.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
double rootCube( double a)
{
double x = a;
double y = 1.0;
const double precision = 0.0000001;
while(fabs(x-y) > precision)
{
x = (x + y) / 2.0;
y = a / x / x;
}
return x;
}
int main(int argc, const char* argv[])
{
if(argc > 1)
{
double a =
strtod(argv[1],NULL);
printf("cubeRoot(%f) = %f\n", a, rootCube(a));
}
return 0;
}
Here, in contrast to the original code of the question, it is more obvious, that x and y are the bounds, which are being improved until a sufficiently accurate solution is found.
With modification of the line in the while block, where y is being updated, this code can also be used to solve similar equations. For finding the square root, for example, this line would look like this: y = a / x.

Related

Getting wrong square-root estimation

I have written a program in C which is calculating for me the square root with the heron procedure. x is my number, r is estimated value and steps are steps. I want to output the difference between the exact value and the value obtained by the heron method. But it seems that my function is not correct. For my calculated value I get no value. Can anyone help me?
#include <stdio.h>
#include <math.h>
int heron (x, r, steps)
{
int k = 0;
double xold, xnew;
double rel_error = 1.0;
while(k <= steps && rel_error > 1e-4) {
++k;
xnew = .5 * (xold + x / xold);
rel_error = (xnew - xold) / xnew;
if(rel_error < 0)
rel_error = -rel_error;
xold = xnew;
}
printf("exact value: %.10f\n", sqrt(x));
return (xnew);
}
int main()
{
int x=4, r=10, steps=50;
printf("%f\n", heron(x, r, steps));
return 0;
}
Change int heron (x, r, steps) to double heron(double x, double r, int steps). You need to declare the types of the parameters, and the function works with floating-point values, so it ought to return float or double, not int, and x and r should be double.
Change double xold , xnew; to double xold = r, xnew;. xold must be initialized before it is used.
Change return sqrt(x); to return xold; to return the value that the function calculated.
With this prefix
int heron (x, r, steps)
{
your function is a function that takes an integer x, another integer r, and a third integer steps. Indeed, it also returns an integer.
The algorithm you describe can be implemented in this way:
#include <stdio.h>
#include <math.h>
double heron(double x, double err)
{
double a = x, b = 1.0;
while (a - b > err) {
a = (a + b)/2.0; /* arithmetic mean */
b = x / a; /* approx to geometric mean */
}
return a; /* or b, depending if you want a value in excess or in defect */
}
int main()
{
printf("heron(2.0, 1.0E-10) = %.10f\n", heron(2.0, 1.0E-10));
printf("sqrt(2.0) = %.10f\n", sqrt(2.0));
}
and that will work.
Read about function parameter type definitions in one of the many references of the C programming languages, e.g. "The C programming language" from Brian Kernighan & Dennis Ritchie, for reference.
$ ./heron
heron(2.0, 1.0E-10) = 1.4142135624
sqrt(2.0) = 1.4142135624
$ _

Trying to Approximate Euler's number in C

I am trying to approximate Euler's number using the formula (1+(1/n))^n.
The compiler is telling me that there is an "expected expression before 'double'"
Here is the code:
#include <stdio.h>
#include <math.h>
int main()
{
int x, y, power;
int num = 1;
int position = 1;
while (position <= 100)
{
num = 1/num;
num = num + 1;
x = num;
power = double pow(x, x); //here
printf("%f", power);
position += 1;
num = position;
}
}
If you want a number to be a double (number with decimals), you need to define it as a double, not an integer. I have this code which should solve your problem. Also make sure to compile gcc FILEPATH -lm -o OUTPUTPATH if you are using UNIX.
#include <stdio.h>
#include <math.h>
int main()
{
double x, y, power, num = 1; //doubles allow for decimal places so declare it as double
int position = 1; //Position seems to only be an integer, so declare it as an int.
while (position <= 100)
{
num = 1/num;
num++;
x = num;
power = pow(x, x);
printf("%f", power);
position += 1;
num = position;
}
}
Another option is a for loop:
#include <stdio.h>
#include <math.h>
int main()
{
double x, y, power, num = 1;
for (int i = 1; i <= 100; i++) {
num = 1/num;
num = num + 1;
x = num;
power = pow(x, x);
printf("%f", power);
position += 1;
num = i;
}
}
If you are trying to approximate Euler's number, I don't see why not just try something like:
static const double E = 2.718281828459045;
I have simply corrected syntax errors in your program, but I don't think it will actually get you E. See this page about calculating E in C.
I'm no C master but isnt just calling double by itself a type declaration and not type casting? wouldnt it be power = (double) pow(x, x); if you are type casting? see: https://www.tutorialspoint.com/cprogramming/c_type_casting.htm
I reworked some mistakes in your code and think it should work now; however, the style, which I kept untouched, is confusing.
#include <stdio.h>
#include <math.h>
int main()
{
double power; //stores floating point numbers!
double num = 1;//stores floating point numbers!
int position = 1;
while (position <= 100)
{
num = 1/num;
num = num + 1;
power = pow(num, position); //x not needed, this is what you ment
printf("%f\n", power); //%d outputs decimal numbers, f is for floats
position += 1;
num = position;
}
}
To improve your code, I would suggest to simplify it. Something along the lines of this
#include <stdio.h>
#include <math.h>
int main()
{
double approx;
for(int iter=1; iter<=100; iter++){
approx=pow((1+1./iter),iter);
printf("%f\n", approx);
}
}
is much easier to understand.

macro equation giving bogus value?

When I run my code, for Y I am consistently getting the value -2147483648, regardless of what value y was fed into my equation.
Here is my code.
#define MAX 1000
#define EQ(y) ((2*(pow(y, 4)))+1)
int check(int value);
int main()
{
int i, y, x;
for(y = 1; y < MAX; y++)
{
i = EQ(y);
if(check(i))
printf("combination found: x = %d, y = %d", sqrt(i), y);
}
}
int check(int value)
{
int x = sqrt(value);
if ((x*x) == value)
return 1;
else
{
return 0;
}
}
After reviewing my code, I realized my problem was with my "int x = sqrt(value)". Aside from the problem with the "value" variable being an int, of course, a bogus value was still being returned due to the fact that the purpose of check is to evaluate whether or not (2*(pow(y, 4)))+1) returned a perfect whole square for any given value of y, and this was not possible due to variable x in check(double value) being datatype integer.
UPDATE: I rewrote my code as follows. I still don't get any correct returns
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
/*
* the solution I implemented basically involved dropping x from the equation, solving for y, checking to see if it has a
* perfect square root. if it does, then x = the squareroot of y in the function EQ.
* original problem: for equation x^2 - 2y^4 + 1 = 0, find all possible solutions up to arbitrary maximum
*/
#define MAX 100000
#define EQ(g) (((pow(g, 4.0)))+1)
int check(double value);
int main()
{
int y, x;
double i;
for(y = 1; y < MAX; y++)
{
i = EQ(y);
if(x = check(i) > 0)
printf("combination found: x = %d, y = %d\n", y, x);
}
}
int check(double value)
{
double x = sqrt(value);
int n = (int) x;
printf("%d\n%f\n%f\n", n*n, value, x);
if (n*n == value)
return n*n;
else
return 0;
}
Read the comments are the top of my code, and the purpose for this selection should be pretty obvious.
You don't have a prototype for double pow(double, double); so the compiler implicitly assumes its signature is int pow(int, int);. Not good!
The solution is to #include the appropriate header at the top of your .c file.
#include <math.h>
Make sure you enable warnings, and if they're already enabled, pay attention to them! Your compiler should warn you about the missing prototype. (It should also spit out a similar warning for printf.)
pow() returns double and you are using integer i to store the return value.
Due to type promotion during expression evaluation the expression:
((2*(pow(y, 4)))+1)
will give a double value and you are storing this in integer type which will give unexpected results.
In reference to your updated question, this line:
if(x = check(i) > 0)
needs to be parenthesized:
if((x = check(i)) > 0)
This is the declaration of pow:
double pow(double x, double y)
Which means it operates in double. By using int instead, variable y is overflowing.

Storing a Randomly generated number in a variable

Im trying to make a program that calculates out a math equation, Im getting stuck on how i generate a random number from 0.00 to 1.00 and store it in a variable a.
this is my code so far, im stuck to how now take that number and store it for future use. I need to store that random number in a, and hten use it in a loop, and then generate a new random number and use it in the 2nd cycle of the loop.
EDIT
this is what i have been working on now, it is suppose to calculate the number of times a random number is inside the area, count it, and then devide by the number of times run, but im not getting any output
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
void initrand(void)
{
srand(time(0));
}
float randfloat(void)
{
return rand()/(float)RAND_MAX;
}
int main(void)
{
int n = 10;
float x;
float y;
float pi = 3.1415;
float rootxy;
initrand();
int z = 0;
int inside = 0;
x = randfloat();
y = randfloat();
float area = 0.25 * pi;
float calculatedpi;
rootxy = sqrt(pow(x,2) + (pow(y,2)));
while (z < n){
if (rootxy > area) {
inside++;
z++;
}
else{
return 0;
}
calculatedpi = (inside/n);
}
printf("%f", calculatedpi);
}
There are a few issues with your code:
You shouldn't use nested functions. Some compilers support them as an extension but it's not standard. Define randfloat and initrand outside main
The function initrand does too little. Why not call srand((time(0)); from main ?
Your initrand function is declared as returning a double but it doesn't return anything (and the way it's named it shouldn't). If you need to use such a function, why not make it return void ?
You should rarely use float. Why not use double ?
That said, you can do this to store that random value:
double randdouble()
{
return rand()/((double)RAND_MAX + 1);
}
int main()
{
double x = randdouble();
/* ... */
}
I think you want something like this:
#include <stdlib.h>
#include <time.h>
void initrand(void)
{
srand(time(0));
}
float randfloat(void)
{
return rand()/(float)RAND_MAX;
}
int main(void)
{
initrand();
float a = randfloat();
return 0;
}
You can't nest functions like in some other languages.
You had non-matching parentheses in the initrand function.
I fixed the declarations of your functions, use void when there are no parameters, initrand doesn't return anything.
Your division by RAND_MAX+1 was a little messed up. Simply divide by RAND_MAX and the result will be in the closed interval [0,1]. And the syntax for the conversion to float was not quite right.
If you want to get random double numbers in a specified range you can use this function
// Return a random double from a to b
double randomDouble(double a, double b)
{
return = ( rand() / ( (double)RAND_MAX + 1.0))
* (b - a) + a;
}

My_sine: what is wrong with my function? [closed]

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.
Okay, so I have tried everything I could think of and haven't been able to figure out how to get this program working. I have tested all the functions used in the main, but included them anyway just in case there is some bug in them. More than likely though, I believe my mistake is in the main.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.14159265359
double int_power(double x, int e);
int main()
{
int my_factorial(int n);
double my_sine_taylor(double x);
double my_sine(double x);
double mod_two_pi(double x);
double get_double(void);
void safeGetString(char arr[], int limit)
char arr[255];
double x,y,ans;
printf("Enter a number: ");
safeGetString(arr[255],255);
my_sine(mod_two_pi(get_double()));
printf("The sine is %f \n", ans);
return 0;
}
/*
int_power should compute x^e, where x is a double and e is an integer.
*/
double int_power(double x, int e)
{
int i = 0;
double ans = 1;
while(i <= e)
{
ans = ans*x;
i++;
}
return ans;
}
/*
my_factorial will find the factorial of n
*/
int my_factorial(int n)
{
int i = n;
int ans = 1;
while(i > 0)
{
ans = ans*i;
i = i-1;
}
return ans;
}
/*
my_sine_taylor computes the approxmiation
of sin(x) using the taylor series up through x^11/11!
*/
double my_sine_taylor(double x)
{
return x - int_power(x,3)/my_factorial(3) + int_power(x,5)/my_factorial(5) -
int_power(x,7)/my_factorial(7) + int_power(x,9)/my_factorial(9) -
int_power(x,11)/my_factorial(11);
}
/*
my_sine(x) should return a very good approximation of sin(x).
It should first reduce x mod 2pi and then map the result into the
upper right quadrant (where the taylor approximation is quite accurate).
Finally, it should use my_sine_taylor to compute the answer.
*/
double my_sine(double x)
{
double ans;
if (x >= 0 && x <= PI/2){
ans = my_sine_taylor(x);
} else if (x > PI/2 && x <= PI){
x=PI-x;
ans = my_sine_taylor(x);
} else if (x > PI && x <= 3*(PI/2)){
x = x-PI;
ans = -(my_sine_taylor(x));
} else {
x=2*PI-x;
ans = -(my_sine_taylor(x));
}
}
/*
mod_two_pi(x) should return the remainder when x
is divided by 2*pi. This reduces values like
17pi/2 down to pi/2
*/
double mod_two_pi(double x)
{
int y;
y = floor(x/(2*PI));
x = x - 2*PI*y;
return x;
}
/*
get_double and safeGetString are used to get floating point
input from the user
*/
double get_double(void)
{
double x;
char arr[255];
x=atof(arr);
}
void safeGetString(char arr[], int limit)
{
int c, i;
i = 0;
c = getchar();
while (c != '\n'){
if (i < limit -1){
arr[i] = c;
i++;
}
c = getchar();
}
arr[i] = '\0';
}
oh my... where to begin?
Let's see...
You have this function:
double get_double(void)
{
double x;
char arr[255];
x=atof(arr);
}
Which you call like this:
my_sine(mod_two_pi(get_double()));
So you're not sending it anything, but you're expecting to get some meaningful value. Basically, arr[255] is not initialized, so it holds garbage. You're taking this garbage and converting it to a float with atof, but that doesn't do anything.
If I had to guess, I'd say that this is what's really breaking your program. The rest of what I wrote below is just commentary.
For some reason, you're declaring all of these functions inside your main. I don't think this should break anything, but it sure is bad coding style.
my_sine_taylor calculates using a 6-element taylor approximation of the sine. Are you sure you need that accuracy? 11! is pretty large, and certain numbers to the 11th power can also be pretty large. You may be introducing unnecessary rounding or overflow errors with this.

Resources