Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have the following equation I need to represent in C:
20 * 2^((1-x)/5)
my c representation is as follows, but it seems like the pow function is always returning a high integer value (1073741824) with my n values ranging from 1-5.
double x = 20 * pow(2.0, (n/5.0));
I assume it is because both arguments are not double values, but I do not see why. Is there a different way to format this equation to get it to work?
I just compiled the example you give and it works
#include <stdio.h>
#include <math.h>
int main () {
for (int n = 1; n <= 5; ++n) {
double x = 20 * pow(2.0, ((1-n)/5.0));
printf("%lf ", x);
}
}
Output
20.000000 17.411011 15.157166 13.195079 11.486984
Make sure you use int n and not unsigned n. In case of unsigned you will get (1 - n) overflow and pow will return inf.
Your compiler is assuming pow() returns an int,
Remeber to #include <math.h> for the proper prototype
#include <math.h>
#include <stdio.h>
// ipow works as pow when the compiler assumes an int return value
int ipow(double base, double exp) {
double res = pow(base, exp);
return *(int*)((void*)&res);
}
int main(void) {
for (int n = 1; n < 6; n++) {
double x = 20 * pow(2.0, ((1-n)/5.0)); // with correct prototype
double y = 20 * ipow(2.0, ((1-n)/5.0)); // when compiler assumes int
printf("n=%d, x=%f, y=%f\n", n, x, y);
}
return 0;
}
See https://ideone.com/XvPWX6
Output:
n=1, x=20.000000, y=0.000000
n=2, x=17.411011, y=422418048.000000
n=3, x=15.157166, y=1240833840.000000
n=4, x=13.195079, y=-1971682192.000000
n=5, x=11.486984, y=-2036727536.000000
Related
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.
This question already has answers here:
Strange behaviour of the pow function
(5 answers)
Closed 5 years ago.
I am having some problems with pow() function in C. When ever run this code, 153 as input, the sum evaluates to 152. However if I dont use pow() function and instead use a for loop to get the value of Nn, the sum evaluates to 153. Can anyone help please explain me this difference?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int main(void) {
unsigned int i, n, sum = 0, N, a = 1, j;
char num[100], x[2] = { 0 };
printf("Determining an armstrong number\n\n"
"Enter a number: ");
fflush(stdin);
gets(num);
n = strlen(num);
for (i = 0; i < n; i++) {
a = 1;
x[0] = num[i];
N = atoi(x);
/* for (j = 1; j <= n; j++)
a *= N;
*/
sum += pow(N, n);
}
n = atoi(num);
if (sum == n)
printf("\nIt is an Armstrong number!\n");
else
printf("\nIt is not an Armstrong number!\n");
return 0;
}
Your C implementation, including its math library, has a bad implementation of pow that returns inaccurate results. (A good pow implementation returns an exact result when the mathematical result is exactly representable in the floating-point format.) For example, for pow(7, 2), your pow may be returning a value slightly under 49. When this is converted to an unsigned int (in the addition to sum), it is truncated, resulting in 48.
To work around this defect in your library, do not use pow for integer arithmetic. Write your own integer arithmetic to get the result you desire. In some circumstances, using round(pow(N, n)) may suffice, but there are considerations of the range of values for which this will work (wide integers may be able to represent integers that double cannot) and sometimes performance. (Another workaround is to get a better C implementation.)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
The task was to find the Area and Volume of a sphere using functions and an additional task was provided to give a function to find the powers of the radius separately (using another function) and then call it in the functions of area and volume.
I can't figure out the way to call the radius function for different powers.
The formula for Surface area is 4*PI*r(power 2)
The formula for the Volume is 4/3 *(PI)*r(power 3)
#include <stdio.h>
#include <math.h>
#include <conio.h>
#define PI 3.142
float surface(int x);
float volume(int y);
int radius();
int main()
{
int r;
float a, b;
clrscr();
printf("Enter the radius :");
scanf("%d", &r);
a=surface(r);
b=volume(r);
printf("Surface Area =%f", a);
printf("\n");
printf("Volume =%f", b);
getch();
return 0;
}
int radius(int z)
{
int f;
f=z*z;
return (f);
}
float surface(int x)
{
float s;
s = 4*PI*radius(x);
return (s);
}
float volume(int y)
{
float v;
v = (4*PI*radius(y)/3);
return (v);
}
I was also instructed to "Refrain from using Arrays or others methods of solving this question."
I cant figure out the way to call the radius function for different powers. An explanation or the correct way to solve this would be helpful!
radius is not really the best name for a function thet computes the square or power of 3. I would call the function power instead. And to make it do different powers you need the exponent as a parameter. You can then use a loop to calculate the power.
/* Calculate the power for exponents >= 0 */
int power(int radius, int exponent) {
int i;
int result = 1;
for (i = 0; i < exponent; i++) {
result = result * radius;
}
return result;
}
You use it like this:
int radius;
// After assigning a value to radius you can call power() like this:
int square = power(radius, 2);
int cube = power(radius, 3);
int cube(int z){
return z * z * z;
}
or
#include<math.h> // at the top
...
int power(int base, int exponent){
return pow(base,exponent);
}
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.
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.