I have a problem with bisection method (recursive implementation) that doesn't work. The program just crashes after entering a&b values ...
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define e 0.0001
#define dbg 1
using namespace std;
double f(double x){
return x*x*x-x-2;
}
double bisection(double a,double b){
double x1;
x1=(b+a)/2;
if(x1>e){
if(f(b)*f(x1)<0)
{
a=x1;
}
else
if(f(a)*f(x1)<0)
b=x1;
bisection(a,b);
}
return x1;
}
int main () {
int a,b;
double root;
printf("a=");
scanf("%d",&a);
printf("b=");
scanf("%d",&b);
if(f(a)*f(b)<0){
root=bisection(a,b);
printf("root %g",root);
}
system("pause");
return 0;
}
I have tried to display some debugging messages, but I couldn't figure it out.
As #Gene pointed out, you never use the result of the recursive call. Further, what you DO return is just the midpoint between a&b, which you don't need recursion to find. (Related?)
Note that, if the 2 ifs used to change either a or b for the recursive call both fail, then you make a recursive call w/ unchanged values of a & b ==> infinite recursion, a sure way to get a segfault.
Related
I'm new to programming and trying to learn C here. Below is my toy program.
#include <stdlib.h>
#include <stdio.h>
int cmp(int a, int b)
{
if (a > b)
{
return a;
}
else
{
return b;
}
}
int main()
{
cmp(10, 20);
printf("testing...");
return 0;
}
My question is, in the main function, cmp() function is called, and the value 10 and 20 is passed into cmp() function.
In this case, b is larger than a, so it goes to the else branch. b should be returned, which is 20 in this case. Why am I not seeing any outputs on the terminal?
Your function will return an integer value; however, in your "main" function you call your "cmp" function but don't do anything with it. The "printf" function is only instructed to print out "testing..." currently. Here is one possible suggestion for checking the output of your function in the "main" function.
int main()
{
printf("Testing the value of cmp(10, 10) is %d\n", cmp(10, 20));
return 0;
}
Hope that helps.
Regards.
I'm a programming rookie who has not yet started. I just learned recursion and there are some problems with the use of recursion. There is a homework is judge prime numbers :using int prime(int x); and return boolean value.
Initially I found that because the variable is initialized and assigned inside the function,the program can't achieve self-increment. Because every time it enters a new level of recursion, the variable will be reassigned. Even if you write a variable auto-increment statement, it will only auto-increase the variables stored in the current recursive stack. Once the variable enters a new recursive level, the variable is only initialized according to the definition and cannot be continuously auto-incremented.
The solution to the failure is as follows:
#include <math.h>
#define false 0
#define true 1
int prime(int x){
double high=sqrt(x);
int low=2;
if((x%low==0 && x!=2) || low>high){
return false;
}
else if(x<2){
return false;
}
else{
return true;
}
low++;
return prime(x);
}
When asking questions, I found a successful solution:
#include <math.h>
#define false 0
#define true 1
int prime(int x){
double high=mysqrt(x);
static int low=2;
if((x%low==0 && x!=2)||low>high){
return false;
}
else if(x<2){
return false;
}
else{
return true;
}
low++;
return prime(x);
}
But I can't understand why using static to modify the variable can make the variable correctly increment when entering a new layer of recursion instead of executing the previous int low=2;
Ask the master to solve the confusion for me, what happened to the two in the memory space?
In addition, there seems to be another solution, which seems to be to set a flag variable, but I did not understand it. Can someone provide other solutions?
In a nutshell, ordinary variables (int low;) get created for each function call independently, while static (static int low = 2;) are created once and shared between all the functions.
However, static is not the best approach to use in such cases, because different function calls may need to have different values of high/low.
Instead, you may add explicit parameters to the function, something like this (the algorithm is wrong, but it's the general principle):
int prime(int x) { return prime_impl(x, 2, sqrt(x)); }
int prime_impl(int x, int low, double high) {
if(x<2) {
return false;
}
else if((x%low==0 && x!=2)||low>high) {
return true;
}
else {
return prime_impl(x, low+1, high);
}
}
Taylor series expansion of cos(x) with a given accuracy
eps
Recursive approach
[Error] overloaded function with no contextual type information
How can I fix this error?
Photo1
#include <stdio.h>
#include <math.h>
double cos(double x, double eps, double s=0,double n=0,double a=0) {
if (abs(n)<1){
cos=cos(x, eps,1,1,1);
}
else {
a = -a*x*x / ((2*n-1) * (2*n));
if (abs(a)<=eps) {
cos=s;
}
else{
cos=cos(x, eps, s+a, a,n+1);
}
}
}
int main () {
double x;
scanf("%f", &x);
cos(x, 0.000000000000001);
}
You included math.h, which has a function named cos, that works a bit differently.
You have overloaded that name (eg. written another function also with the name cos) but have not given the compiler any means to deduce which version of cos you want to call.
Fix this by naming your function something different and unique.
Here's my attempt at a fix:
double TaylorCOS(double x, double eps, double s=0,double n=0,double a=0)
{
if (abs(n)<1)
{
return TaylorCOS(x, eps,1,1,1);
}
a = -a*x*x / ((2*n-1) * (2*n));
if (abs(a)<=eps)
{
return s;
}
return TaylorCOS(x, eps, s+a, a,n+1);
}
You can't assign to a function identifier like you do in
cos=s;
cos=cos(x, eps, s+a, a,n+1);
Neither in C, nor in C++. This program is broken beyond repair.
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 8 years ago.
Improve this question
My professor gave us this code in class to show how a program works and said "go home and try it and you'll see it works".... well after 30 minutes I cannot get it to run. can someone please help me and point me in the right direction. Thank you!
-I get function definition on the end "double g(double x)"
-On the first else where x_left = x_mid control reaches end of non-void function
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define FALSE 0
#define TRUE 1
#define NO_ROOT -99999.0
//function prototypes
double bisect(double, double, double, double f(double farg));
// evaluation of function
double g(double);
double h(double);
int main(void) {
double x_left, x_right, epsilon, root; //declare variables
// get endpoint and error tolerance
printf("\nEnter interval endpoints > ");
scanf("%lf%lf", &x_left, &x_right);
printf("\nEnter tolerance > ");
scanf("%lf", &epsilon);
//use bisect function to look for roots of functions
printf("\n\n For function g(x)");
root = bisect(x_left, x_right, epsilon, g);
if (root != NO_ROOT)
printf("\n g(%.7f) = %e\n", root, g(root));
printf("\n\n For function h(x)");
root = bisect(x_left, x_right, epsilon, h);
if (root != NO_ROOT)
printf("\n h(%.7f) = %e\n", root, h(root));
system("pause");
return (0);
}
// bisection method program coding
double bisect(double x_left, double x_right, double epsilon, double f(double farg)){
double x_mid, f_left, f_right, f_mid;
int root_found;
// computes function at initial end points
f_left = f(x_left);
f_right = f(x_right);
// if no change in sign
if (f_left * f_right > 0) {
printf("\nmay not be no root in [%.7f, %.7f]\n\n", x_left, x_right);
return NO_ROOT;
}
// searches as long as interval size is large enough
root_found = FALSE;
while (fabs(x_right - x_left) > epsilon && !root_found) {
// compute the mid point
x_mid = (x_left + x_right) / 2.0;
f_mid = f(x_mid);
if (f_mid == 0.0) {
root_found = TRUE;}
else if (f_left * f_mid < 0.0) {
x_right = x_mid;
} else {
x_left = x_mid;
}
// trace loop execution
if (root_found)
printf("\nRoot found at x = %.7f , midpoint of [%.7f, %.7f] ", x_mid, x_leftx_right);
else
printf("\nNew interval is [%.7f, %.7f] \n\n", x_left, x_right);
//if there is a root
return ((x_left + x_right)/2.0);
}
// functions for which roots are sought
double g(double x){
return (5 * pow(x, 3.0) - 2 * pow(x, 2.0) +3);
}
double h(double x){
return (pow(x, 4.0) - 3 * pow(x,2.0) - 8);
};
}
I get an error on this line:
printf("\nRoot found at x = %.7f , midpoint of [%.7f, %.7f] ", x_mid, x_leftx_right
saying that x_leftx_right is undeclared.
If I change this to x_left, x_right then it compiles OK except for "undefined reference to g" and "undefined reference to h".
The reason for the undefined reference to g is that you never provided a function definition for the function g that was prototyped by double g(double);. You did provide a nested function g within bisect. Nested functions are a non-standard extension, and bisect::g is a different function to g. Similarly for h.
To fix this, move the definitions of g and h to be after the end of the bisect function; instead of inside that function.
The reason for your "control reaches end of non-void function" warning is probably because there is no return statement after the while loop.
Your line return ((x_left + x_right)/2.0); line is within the loop begun by while (fabs(x_right - x_left) > epsilon && !root_found) {. If this loop finishes by the loop condition no longer being true, then the execution hits the end of the function without returning anything.
NB. If you indent your code properly so that you line up { then you are less likely to have this sort of problem. Your editor should have a key that you can use to find matching curly-braces. Also, operating your compiler in strict standard mode would have given an error about the use of nested function.
`
I use this code, but get an segmentation error. What is wrong here ?
GNU nano 2.2.6 File: taak8.c
#include<stdio.h>
double recursie(double som,double oud, double x, int stap){
double y = oud*x/stap;
if(y >= 1/1000){
return recursie(som+y,y,x,stap++);
} else {
return som;
}
}
double exp(double x){
return recursie(1,1,x,1);
}
int main(){
double inp;
scanf("%lf",&inp);
printf("your result %lf",exp(inp));
return 0;
}
if(y >= 1/1000) problem is there. 1/1000 will always be 0. so put 0 there directly.
But i think you wanted to do this below , try this instead
if(y >= 1.0/1000)
and this also
recursie(som+y,y,x,++stap);
use ++stap to increment stap instead of stap++.Because you have to send the incremented value of stap to recursive function call.
You need to increment your step before you call the recursive step, not after. In other words, you need to use pre-increment, not post-increment:
return recursie(som+y,y,x,stap+1);