macro equation giving bogus value? - c

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.

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
$ _

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

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.

Error: too few arguments to function 'twice'

I'm new to C and I'm having some problems in this code where I'm getting these errors.
sum2.c: In function 'main':
sum2.c:22:6: warning: 'z' is used uninitialized in this function [-Wuninitialized]
int z = twice(x, z);
On my code I needed to add a fuction twice, which, given a number, calculates its double, using only the elementary operations and the sum function. And I don't know if the way I put the function is correct.
//USER
//3532
#include <stdio.h>
int sum(int x, int y){
return y == 0 ? x : sum(x+1, y-1);
}
int twice(int x, int z){
z = x * x;
return 0;
}
int main(void){
int x;
int y;
scanf("%d%d", &x, &y);
int z = twice(x, z);
printf("%d\n", z);
return 0;
}
The instructions say that twice is "given a number", but you've defined it as taking two numbers. It only needs one parameter.
And you're supposed to use your sum() function. There's no need to multiply x*x (that's the square of the number, not twice the number), nor is there any point in assigning a variable in the return statement.
You only need to read one number as input to test this.
#include <stdio.h>
int sum(int x, int y)
{
return y == 0 ? x : sum(x+1, y-1);
}
int twice(int x)
{
return sum(x, x);
}
int main(void)
{
int x;
int w;
scanf("%d", &x);
int w = twice(x);
printf("%d\n", w);
return 0;
}
According to your description the function twice should accept only one argument.
So this function definition
int twice(int x, int z)
{
z = x * x;
return 0;
}
does not make sense. Moreover the function always returns 0.
Also take into account that the type int is a signed integer type. The user can input a negative number. In this case your function sum will yield a wrong result.
The sum of two integers of the type int can be too big to fit in an object of the type int. That is there can be for example an overflow.
The functions can be defined the following way as it is shown in a demonstrative program.
#include <stdio.h>
long long int sum( int x, int y )
{
return y == 0 ? ( long long int )x
: sum( y < 0 ? x - 1 : x + 1, y < 0 ? y + 1 : y - 1 );
}
long long int twice( int x)
{
return sum( x, x );
}
int main(void)
{
int x;
printf( "Enter a number: " );
scanf("%d", &x);
long long int result = twice( x );
printf("The sum is %lld\n", result );
return 0;
}
Its output might look like
Enter a number: -5
The sum is -10
Or
Enter a number: 5
The sum is 10

commenting a printf statement stops output

I am trying to write C code to perform some mathematical calculation. I was using a printf statement to check the print the variable. When I was done with the code, and I was getting the desired output, I commented the line out. However, after doing that, I am not getting any output. Uncommenting the line gets the desired output back.
#include <stdio.h>
#include <math.h>
#define M 1000
const double eps = 1.110223e-16;
const double delta = 1.110223e-16;
void bisection(double (*fn)(double), double a, double b) {
//Bisection algorithm
double w, c, u, v, e;
int i;
u = (*fn)(a);
v = (*fn)(b);
e = b - a;
if(signbit(u) == signbit(v)) {
printf("Stopping due to same sign\n");
return;
}
for(i = 0; i < M; i++) {
printf("%d\n", i);
e = e / 2;
c = a + e;
w = (*fn)(c);
//Stopping conditions epsilon and delta
if(abs(e) <= eps || abs(w) <= delta) {
printf("Root is %e\n", c);
return;
}
if(signbit(w) == signbit(u)) {
//Means that root lies in [c,b]
a = c;
u = w;
} else {
// Means root lies in [a, b]
b = c;
v = w;
}
}
}
double problem_a(double x) {
return (pow(x, -1) - tan(x));
}
int main(int argc, char *argv[])
{
double (*fn)(double);
fn = &problem_a;
bisection(fn, 0.0 + eps, M_PI/2 - eps);
return 0;
}
The output I am getting is: Root is 7.853982e-01
I get no output if I comment the file.
I am using the gcc compiler version 4.8.3
What can be a possible explanation for this behaviour?
You are calling abs without a declaration! This means that the compiler doesn't know the expected types of any arguments.
You pass a double argument to abs (which expects an int). This invokes undefined behaviour, which means anything can happen. And in your case it does, since you get different results if you add an unrelated printf.
You can fix the undefined behaviour by adding a declaration for abs. Indeed, if you #include <stdlib.h> the problem with the printf goes away.
This won't make your program correct, though. As pointed out by #cremno in the comments, you should use fabs to get the absolute value of a double.
So, modify the line that calls abs like this:
if(fabs(e) <= eps || fabs(w) <= delta) {
Running the modified program prints out
0
1
2
3
<skipping a few lines>
51
52
Root is 8.603336e-01

Void Function Error?

So I had to write a program that used the Pythagorean Threes concept where if you entered a number it would give you all the combinations less than that number that would produce a correct a^2 + b^2 = c^2 output.
Not sure if I explained the assignment well, but basically I understand the logic or at least I think I do I was wondering if you guys could help me find out why I am getting this error....
For the last line of my code it gives me, "warning: control reaches end of non-void function [-Wreturn-type]," As the error any idea what I am doing wrong?
#include <stdio.h>
int main(void){
int x = 0, y = 0, z = 0, n;
int count = 0;
printf("Please Enter A Positive Integer: \n");
scanf("%d", &n);
while(z <= n){
while(y < z){
while(x < y){
if(x * x + y * y == z * z)
printf("%d: \t%d %d %d\n", ++count, x, y, z);
x += 1; }
y += 1; }
z += 1;
}
}
int main(void){
Your function header indicates that you're looking to return an int. To fix this, return a number (0 usually indicates a normal termination) at the end of your function.
To break it down a little,
int indicates the return type,
main is the method name, and
void indicates that there are no parameters for this method.
Your main function is declared to return an int, but you don't return anything.
put return 0; before the closing brace of your main.
int main( void )
{
// ... code ...
return 0;
}

Resources