While loop not working with bool statements in C (beginner!) - c

I'm learning the basics right now and am making a simple game using a basic graphics library provided by my uni.
There is a projectile thrown (the path of which is drawn)
an obstacle (a wall) - which the projectile can't pass through so must go over
and a target (must also appear solid so line stops being drawn when it is hit)
Right now my projectile is being thrown right through the wall
The issue is with the while loop
Any conditions I add (after (y_displacement < FLOOR_HEIGHT)) have had no effect
(This projectile on its own stops drawing when y_displacement => FLOOR_HEIGHT (Y-Axis is inverted), but any addition of bool statements or attempts at using bool (after #including too) to stop the projectile line being drawn don't make any changes.
TRIED BOOL FOR WALL (doesn't change anything):
bool hit_wall = false;
while ((y_displacement < FLOOR_HEIGHT) && (hit_wall == false))
{
time = (x_displacement - X_HAND) / x_velocity; //speed = distance/time
y_displacement = (Y_HAND - y_velocity * time) - (GRAVITY * pow(time, 2)/2);
GFX_DrawLineTo(x_displacement, y_displacement, 3);
x_displacement += 1;
if ((x_displacement == (X_MAX/2.5)) && ((y_displacement > (Y_MAX/2))))
{
hit_wall = true;
}
}
}
If I can manage to sort this out then I should be able to do the same for my target..
Is there something wrong with what I'm doing?
BACKGROUND:
The full function is this:
void throwBall(int(x_position), int(y_position))
{
GFX_SetColour(YELLOW);
int x_mouse;
int y_mouse;
int x_distance;
int y_distance;
double angle;
float initial_velocity;
float x_velocity;
float y_velocity;
float time;
GFX_MoveTo(X_HAND, Y_HAND);
GFX_GetMouseCoordinates(&x_mouse, &y_mouse);
x_distance = x_mouse - X_HAND;
y_distance = y_mouse - Y_HAND;
angle = getAngle(x_distance, y_distance);
initial_velocity = sqrt(pow(x_distance, 2) + pow(y_distance, 2));
//these have been divided by 5 as the magnitude was too large for the window
y_velocity = (initial_velocity * sin (angle) - GRAVITY * time)/(X_MAX/256);
x_velocity = (initial_velocity * cos (angle))/(X_MAX/256);
float y_displacement;
float x_displacement;
x_displacement = X_HAND;
y_displacement = Y_HAND;
bool hit_wall = false;
while ((y_displacement < FLOOR_HEIGHT) && (hit_wall == false))
{
time = (x_displacement - X_HAND) / x_velocity; //speed = distance/time
y_displacement = (Y_HAND - y_velocity * time) - (GRAVITY * pow(time, 2)/2);
GFX_DrawLineTo(x_displacement, y_displacement, 3);
x_displacement += 1;
if ((x_displacement == (X_MAX/2.5)) && ((y_displacement > (Y_MAX/2))))
{
hit_wall = true;
}
}
}

if ((x_displacement == (X_MAX/2.5)) && ((y_displacement > (Y_MAX/2))))
{
hit_wall = true;
}
you use flaot values, and due to some reasons (values are aprroximatelly) you almost never get in this if.
you should use >, >=, < , <= poerators, but it also will not help you in 100% of cases.
best choice will be to use epsilon (Observational error, Neighbourhood)
like
float eps = 0,0000001f;
if ( abs(x_displacement - (X_MAX/2.5) ) < eps
&& y_displacement > ( (Y_MAX/2) - eps ) )
{
hit_wall = true;
}

expanding on previous answers regarding floating point equivalence and round off error, another way to do it is multiply your float or double value by some factor of 10 to move the decimal point to the right, then cast it to an int or long it. Then you can do a boolean comparison which will be on integers which will work reliably. I mention this because it can sometimes be easier to code and also read easier than doing the epilson method (which you would also have to do an absolute value on) described in the other answer .
The big thing to recognize is the factor of 10 by which you multiply with or set epsilon to.
Do not go crazy and multiply by something like 1e9 or set epsilon = 1e-9 when you don't need to because that can re-introduce the same problem.
For example if your variables for distance are in meters then you need to recognize you do not need resolution greater than ???. Let's use 1/100 of a millimeter as an example... as far as you are concerned 1.230012345mm == 1.230456789mm. So then multiply by 1e5 then cast to int or do epsilon=1e-5;. Same principle applies for units of inches, you typically do not need resolution greater than 0.0001" for anything so multiply by 1e4 or epsilon = 1e-4.
/* example */
# define D2I 1e2 /* dbl to int factor, 0.01mm resolution */
double x_displacement; /* units of millimeters for this example*/
double y_displacement; /* units of millimeters for this example*/
/* whatever previous calculations result in...
x_displacement having value of 3.00000249687738566
y_displacement having value of 120.00000085639820699
out past 6 or so decimal places a float or double will have arbitrary numbers, so don't multiply by some huge 1e12 number
*/
if ( ( (int)(x_displacement * D2I) == (int)((X_MAX / 2.5) * D2I ) ) &&
( (int)(y_displacement * D2I ) > (int)((Y_MAX / 2 ) * D2I ) )
)
{
hit_wall = true;
}

Related

C Physics engine

I am working on a fabric simulator at low level, I have done some work and at this point there are some points where I would appreciate help.
The input of the program is a DRF file. This is a format used in sewing machines to indicate the needles where to move.
The 2D representation is accurate, I parse the DRF info to a polyline, apply tensions and I extrude this in a openGL render.
Now I am trying to achieve the 3D ZAxis physics. I tried two methods:
1) Asuming information
First method is based on constrains about the process of manufacturing:
we only take care of the knots where a set of yarns interact and comupte z separation in this crucial points. The result is regular: good in a lot of cases but with a lot of botched jobs in order to avoid causistincs where this is not a good assumtion (for example, doing beziers, collisions in zones between this crucial points). We desist on this alternative when we saw there was a lot os causistic we would have to hardcode,probably creating aditional gliche.
2) Custom 2D Engine
The second attempt is to aprox the yarns with box colliders 2D, check collisions with a grid, and compute new Z in funcion of this. This is by far more expensive, but leads to a better results. Although, there is some problems:
The accuracy of box colliders over the yarn is not absolute ( there are ways to solve this but it would be great to read some alternatives)
There is not iterative process:
First we compute collisions pairwise, and add to each collider a list of colliding colliders. Then, we arrange this list and separate the Z axis in function of yarn's radius with center 0.The last step is to smooth the results from discrete z to a beziers or smoothing filters. This leads to another glitches.
If I extend this recomputation to all the collisions of the current collisions, I get weird results because z changes are bad propagated( maybe I am not doing good this point)
Some colliders are recomputed wrong ( first computed yarns have more posibilites to be altered for the last ones, leading on gliches)
This is the result for the secdond approach ( without recompute z's on smoothing step):
And some of the glicthes (mainly in the first yarns computed:
This is the collisions engine:
Details of bad aproximated curves:
At this point I have some questions:
Can I fix this glitches (or a great part at least)?
Glitches about bad aproximation and glitches for z recomputation
A 3D engine like ODE could do the job in a reasonable time?
If you need some specific code don't hestiate on ask for it.
EDIT: Ok, let's narrow the thing.
Yesterday I tried some open source engines without achieving good results.
500 collisions with joints are crashing the simulation. so I discard it.
My problem:
A: How I generate the yarns:
I have a set of points and I trace beziers between them.
CUBIC_BEZIER(p1x,p1y,p1z,p2x,p2y,p2z,p3x,p3y,p3z,p4x,p4y,p4z, npunts);
For each pair of points I add a collider:
p1.x = *(puntlinaux + k*NUMCOMP);
p1.y = *(puntlinaux + k*NUMCOMP + 1);
p2.x = *(puntlinaux + k*NUMCOMP + 4);
p2.y = *(puntlinaux + k*NUMCOMP + 5);
*bc = getCollider(&p1,&p2,x,y,z, radi_mm_fil , pbar->numbar);
where
BoxCollider2D getCollider(punt_st* p1, punt_st* p2, float *x, float *y, float *z, float radiFil,int numbar){
BoxCollider2D bc;
bc.numBar = numbar;
int i;
for(i = 0; i < MAX_COLLIDERS; i++) {
bc.collisions[i] = NULL;
}
bc.isColliding = 0;
bc.nCollisions = 0;
bc.nextCollider = NULL;
bc.lastCollider = NULL;
bc.isProcessed = 0;
punt_st center;
p1->x = p1->x;
p2->x = p2->x;
float distance = distancePunts_st(p1,p2);
bc.angle = atan2((p2->y - p1->y),(p2->x-p1->x));
//bc.angle = 0;
//DEBUG("getCollider\n");
//DEBUG("angle: %f, radiFil: %f\n", bc.angle*360/(2*3.141592), radiFil);
//DEBUG("Point: pre [%f,%f] post:[%f,%f]\n", p1->x, p1->y, p2->x, p2->y);
p1->y = p1->y;
p2->y = p2->y;
bc.r.min = *p1;
bc.r.max = *p2;
center = getCenterRect(bc.r);
bc.r.max.x = (center.x - distance/2);
bc.r.max.y = (center.y + radiFil) - 0.001f;
bc.r.min.x = (center.x + distance/2);
bc.r.min.y = (center.y - radiFil) + 0.001f;
bc.xIni= x;
bc.yIni= y;
bc.zIni= z;
return bc;
}
Then I add the collider to a grid to reduce complexity on comparisons
and check the collisions with Separated Axis Theorem
DEBUG("calc_sapo: checking collisions\n");
checkCollisions();
After that, I resolve the collisions leading on a discrete z aproximation.
DEBUG("calc_sapo: solving collisions\n");
resolveCollisions();
And then I apply a smooth function. This is the point where I am lost.
DEBUG("smoothing yarns\n");
smoothYarns();
To keep it simple, let's assume smoothYarns() does a simple mean value with the last and next z value:
for each collider of each yarn:
float aux = (*bc->zIni + *(bc-1)->zIni + *nextBC->zIni)/3;
float diff = aux - *bc->zIni;
*bc->zIni = aux;
Then we have to update all the colliders in contact with this recomputed collider:
void updateCollider(BoxCollider2D *bc, float diff){
int i ;
for(i = 0; i < bc->nCollisions; i++){
*bc->collisions[i]->zIni += diff;
}
}
This last step is messing up all the simulation because z's are accumulating theirselves ...
I want to know why this does not tend to converge as I expected and possible solutions for this problem.
EDIT2:
This is the algorithm that detects collisions:
For each collider in the grid position
Compare with others in the grid
if colliding: add the colliding collider to the current collider
For each yarn:
Go trhough all the colliders (linked list)
For each collider from a yarn:
Bubble sort collision yarns in function of their z order
Compute z based on yarns radius (centered on 0)
float computeZ(BoxCollider2D *array[], int nYarns, BoxCollider2D *bc){
int i, antBar;
float radiConflicte = 0;
float zMainYarn;
finger_st *pfin;
antBar = -1;
for(i = 0; i<nYarns; i++){
if(pfin != array[i]->pfin){
float radiFil = getRadiFromBC2D(*array[i]); // veure getCollider
radiConflicte += radiFil;
pfin = array[i]->pfin;
}
}
antBar = -1;
pfin = NULL;
for(i = 0; i<nYarns; i++){
float radiFil = getRadiFromBC2D(*array[i]); // veure getCollider
if(pfin != array[i]->pfin){
radiConflicte -= radiFil;
*(array[i]->zIni) = radiConflicte;
if(array[i] == bc) zMainYarn = *(array[i]->zIni);
radiConflicte -= radiFil;
pfin = array[i]->pfin;
}
else *(array[i]->zIni) = *(array[i-1]->zIni);
}
This leads in a approach where the last yarns processed can alter the firsts ones, and, in last instance, to glitches.
How I can avoid that?
Thanks a lot!

OpenCV Object Detection Memory Issue

The code I wrote below is objection detection using size-invariant template matching. This technique was detailed in the following site: https://www.google.com/url?hl=en&q=http://www.pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/&source=gmail&ust=1489552541603000&usg=AFQjCNHSfgL_RTy-o5SMyCmWELFbsfOOTw
The function works fine. However, when I am running too many iterations in the while loop, OpenCV Error: Insufficient Memory will occur.
I can't seem to figure out why I'm running into this error as I'm releasing the the matrix data that I'm creating in cvCreateMat in every iteration. The memory error occurs after running the loop several times and in the function cvMatchTemplate. Am I missing another source of error? I am writing this code in C on the LCDK.
Function:
double minVal = 0.0;
double maxVal = 0.0 ;
CvPoint minLoc;
CvPoint maxLoc;
double ratio = 1.0;
CvMat* mask2 = NULL;
//for containing the maximum values
CvMat* resized_source;
CvMat* result; //result stored for every shapes
while (1){
// All templates are sized around the same
if(width_curr <= template->cols || height_curr <= template->rows)
break;
resized_source = cvCreateMat(height_curr,width_curr,CV_8UC1);
cvResize(source_close_edge_dist_8,resized_source,CV_INTER_LINEAR);
result = cvCreateMat((resized_source->rows)-(template->rows)+1, (resized_source->cols)-(template->cols)+1, CV_32FC1);
cvMatchTemplate(resized_source, template, result, CV_TM_CCOEFF);
//Detecting several objects
cvMinMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, mask2);
*(max_all+*size) = maxVal;
(max_all_point+*size)->x = maxLoc.x;
(max_all_point+*size)->y = maxLoc.y;
*(max_all_ratio+*size) = sqrt(ratio);
*size = *size + 1;
// move on to next resizing
ratio -= 0.04;
width_curr = sqrt(ratio)*width;
height_curr = sqrt(ratio)*height;
minVal = 0.0;
maxVal =0.0 ;
cvReleaseData(resized_source);
cvReleaseMat(&resized_source);
cvReleaseData(result);
cvReleaseMat(&result);
}

Garbage storage, programming in C

I'm new programing in C. I have a main code with 781 lines that is out of control because garbage value is stored in vectors. A short part of the main code is shown below where it calls a subroutine called diff_conv_intermedia1.
diff_conv_intermedia1(&factorteta,&N,ID,DIFF,X1_intermedia,Y1_intermedia,X1C_intermedia,Y1C_intermedia,CU1_intermedia,CV1_intermedia,AW1_intermedia,AE1_intermedia,AS1_intermedia,AN1_intermedia,AP1_intermedia,Q1_intermedia,FXI1,FYI1,FI_intermedia1,1,2,1,1);
int q,w;
for(q=1;q<(*factorteta_Ptr)*2+1;q++)
{
for(w=1;w<(*N_Ptr)+1;w++)
{
printf("%lf\n",AP1_intermedia[q][w]);
}
}
So the subroutine shown below. When I print the results inside the subroutine, everything is OK, but when I print the results outside the subroutine, in the main code, garbage is stored in the vectors as AP1_intermedia. I don't know what could be wrong. I repeat the same procedure with other subroutines and I don't have any errors.
int diff_conv_intermedia1(int *factorteta_Ptr,
int *N_Ptr,
int ID,
double DIFF,
double X[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double Y[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double XC[(*factorteta_Ptr)*2+2][*N_Ptr+2],
double YC[(*factorteta_Ptr)*2+2][*N_Ptr+2],
double CU[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double CV[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AW[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AE[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AS[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AN[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AP[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double Q[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double FX[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double FY[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double FI[(*factorteta_Ptr)*2+1][*N_Ptr+1],
int WBC,int EBC,int SBC,int NBC)
{
int i,j;
double value,* valuePtr;
double AED, AWD, AND, ASD;
double AEC, AWC, ANC, ASC;
valuePtr = &value;
// Diffusive coefficients
for(i=1;i<(*factorteta_Ptr)*2+1;i++)
{
for(j=1;j<*N_Ptr+1;j++)
{
AWD = -DIFF*(Y[i][j-1]-Y[i-1][j-1])/(XC[i][j]-XC[i][j-1]);
AED = -DIFF*(Y[i][j]-Y[i-1][j])/(XC[i][j+1]-XC[i][j]);
AND = -DIFF*(X[i][j]-X[i][j-1])/(YC[i+1][j]-YC[i][j]);
ASD = -DIFF*(X[i-1][j]-X[i-1][j-1])/(YC[i][j]-YC[i-1][j]);
// Convection term
if(ID==2)
{
max1_or_min2(CU[i][j-1],1,&value);
AWC=-*valuePtr;
max1_or_min2(CU[i][j],2,&value);
AEC=*valuePtr;
max1_or_min2(CV[i-1][j],1,&value);
ASC=-*valuePtr;
max1_or_min2(CV[i][j],2,&value);
ANC=*valuePtr;
}
if(ID==1)
{
AWC =-CU[i][j-1]*(1.0-FX[i][j-1]);
AEC =CU[i][j]*FX[i][j];
ASC =-CV[i-1][j]*(1.0-FY[i-1][j]);
ANC =CV[i][j]*FY[i][j];
}
// Set Coefficients matrix
AW[i][j] = AWD+AWC;
AE[i][j] = AED+AEC;
AS[i][j] = ASD+ASC;
AN[i][j] = AND+ANC;
AP[i][j] = -(AE[i][j]+AW[i][j]+AN[i][j]+AS[i][j]);
Q[i][j] = 0.0;
}
}
// West Boundary - Inlet B.C
for(i=1;i<(*factorteta_Ptr)*2+1;i++)
{
if(WBC==1) Q[i][1] = Q[i][1]-AW[i][1]*FI[i][0];
if(WBC==2) AP[i][1] = AP[i][1] + AW[i][1];
AW[i][1] = 0.0;
// East Boundary - (1)Dirichlet (2)ZERP-GRAD Outflow B.C
if(EBC==1) Q[i][*N_Ptr] = Q[i][*N_Ptr] - AE[i][*N_Ptr]*FI[i][*N_Ptr+1];
if(EBC==2) AP[i][*N_Ptr] = AP[i][*N_Ptr] + AE[i][*N_Ptr];
AE[i][*N_Ptr] = 0.0;
}
// South Boundary - (1)Dirichlet (2)ZERO-GRAD
for(j=1;j<*N_Ptr+1;j++)
{
if(SBC==1) Q[1][j] = Q[1][j] - AS[1][j]*FI[0][j];
if(SBC==2) AP[1][j] = AP[1][j] + AS[1][j];
AS[1][j] = 0.0;
// North Boundary - (1)Dirichlet (2)ZERO-GRAD
if(NBC==1) Q[(*factorteta_Ptr)*2][j] = Q[(*factorteta_Ptr)*2][j] - AN[(*factorteta_Ptr)*2][j]*FI[(*factorteta_Ptr)*2+1][j];
if(NBC==2) AP[(*factorteta_Ptr)*2][j] = AP[(*factorteta_Ptr)*2][j] + AN[(*factorteta_Ptr)*2][j];
AN[(*factorteta_Ptr)*2][j] = 0.0;
}
// Print
int l,k;
for(l=1;l<(*factorteta_Ptr)*2+1;l++)
{
for(k=1;k<*N_Ptr+1;k++)
{
printf("%lf %lf %lf %lf\n",AP[l][k],AS[l][k],AN[l][k],FI[l][k]);
}
}
return 0;
}
If anybody wants I can send all code, but have many extensions.
In your function declaration:
double AP[(*factorteta_Ptr)*2+1][*N_Ptr+1]
I don't quite think this is doing what you think it is doing. While I haven't seen something like this myself before, I believe that this is telling the compiler to create a variable length 2D array for you based on the other given parameters. Then, you fill in these values in your function. But, because you don't return this value nor do you declare it as pass by reference, it is thrown away when you return, thus the work is lost and you have garbage in your array in main(). Better form would be to create this array in main(), then pass it in by reference something like double *AP[][], or return this array upon exit, or hack things up even worse than this function and just make it a global so that you can see it anywhere.

Equation returning 1.#QO

I've tried searching for anything similar about my issue on several websites, including this one, but none I've found so far are similar. After searching about the term 1.#QO, I found something about quiet NaN, but I'm new to C in general, so I don't really understand the issue .
I'm trying to take the x and y values of a joystick, and when then use a formula for distance to find the distance between the joystick's position, and the joystick's natural resting position (0,0).
If it matters, I'm trying to do this in RobotC.
#pragma config(Hubs, S1, HTMotor, none, none, none)
#pragma config(Sensor, S1, , sensorI2CMuxController)
#pragma config(Motor, mtr_S1_C1_1, DriveMotor, tmotorTetrix, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard !!*//
#include "JoystickDriver.c"
int calculateDrivePower(int joyStickX, int joyStickY)
{
if (joyStickX != 0 & joyStickY != 0)
{
int joyDistance = (sqrt(pow((joyStickX - 0),2)+ pow((-joyStickY - 0),2)));
joyDistance = ((joyDistance/127)*100);
return (joyDistance);
}
else
{
return 0;
}
}
task main()
{
int previousJoySlope = 0;
int TurnSpeed = 70;
while (true)
{
getJoystickSettings(joystick);
if (abs(joystick.joy1_x1) > 10 || abs(joystick.joy1_y1) > 10)
{
writeDebugStreamLine("Test successful.");
motor[DriveMotor] = calculateDrivePower(joystick.joy1_x1,joystick.joy1_y1);
}
}
}
If anyone could provide any insight, that'd be fantastic, thanks.
if (joyStickX != 0 & joyStickY != 0)
{
int joyDistance = (sqrt(pow((joyStickX - 0),2)+ pow((-joyStickY - 0),2)));
joyDistance = ((joyDistance/127)*100);
return (joyDistance);
}
The first issues that appears is the conditional within the if statement. The you have a single & that most likely should be &&:
if (joyStickX != 0 && joyStickY != 0)
(note: likely should be is used above because you can provide a conditional using a logical & of the tests joystickx != 0, but in this case it provides the same result. In that case, I would suggest the more readable && be used)
The next part of the code is simply the vector distance between 0,0 and the present position of the joystick. Of the general form dist^2 = (x2-x1)^2 + (y2-y1)^2 in your case x1,y1 = 0,0. Taking the square root of both sides provides dist = sqrt((x2-x1)^2 + (y2-y1)^2), or in C notation:
dist = (sqrt(pow((joyStickX - 0),2)+ pow((-joyStickY - 0),2)));
Next you have a scaling applied of dist = dist * 100/127 which provides the final distance returned. Hopefully this will help you understand what the code is doing.

Function definition not allowed / [closed]

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

Resources