[SOLVED] messed up my loop with pointers. help please.
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
we are trying to create a script that solves for square root. i have a working function provided by the prof. i think my error is in my while loop, but im not 100%.
Code:
int main(void)
{
double N, NG, LG, *PLG, epsilon, root; // setting all variables to type double
epsilon = 0.005; // setting error tolerance to 0.005
LG = 1.0; // setting initial guess value
printf("\nPlease enter the number you wish to find the square root: ");
scanf("%lf",&N); // getting input from user
NG = 0.5 * (LG + (N / LG));
while ( NG - LG <= epsilon )
{
*PLG=NG;
NG = 0.5 * (*PLG + (N / *PLG));
}
printf("The square root of %.2lf is %.3lf\n", N, NG);
}
This runs the first time, but then stops. it never goes back in when the error is outside of my epsilon value.
Code:
ssma-imac:ENG-3211 ssma$ gcc -o hw_4_1 hw_4_1.c
ssma-imac:ENG-3211 ssma$ ./hw_4_1
Please enter the number you wish to find the square root: 4
The square root of 4.00 is 2.500
when i run this by hand it should take 3 attempts and come up with an answer of 2.0006 that should be reported as 2.000.
im guessing that by setting NG = 0.5 * ( LG + (N / LG)); before the while loop that is causing the issue.
I just dont know how to get the NG inside of the while loop for the test conditions for my error checking.
pointing me in the right direction would be great. please no exact code changes or providing of exact code, examples are great. this is homework.
side not question. in class the prof. indicated that as long as you have a variable declared you dont need to also declare the pointer value if they are the same. ex:
doubt LG;
*LG = NG
That is what one of his examples had and I asked about it in class. He indicated that this is fine because *LG will point to the memory location of LG, but when i *LG = NG it will change the value stored at NG to the value pointed to by LG. I think i said that semi clear.
I was receiving unary * errors when compiling with the above example. I had to put *PLG at the top of my script to get the unary error to go away...
well i have made some progress, but now my test condition is never coming true:
Code:
int main(void)
{
double N, NG, LG, *PLG, epsilon, root; // setting all variables to type double
epsilon = 0.005; // setting error tolerance to 0.005
LG = 1.0; // setting initial guess value
printf("\nPlease enter the number you wish to find the square root: ");
scanf("%lf",&N); // getting input from user
//NG = 0.5 * (LG + (N / LG));
// while ( NG - LG <= epsilon )
// {
//*PLG=NG;
// NG = 0.5 * (LG + (N / LG));
// }
// printf("The square root of %.2lf is %.3lf\n", N, NG);
//}
for (LG = 1; NG - LG <= epsilon; LG = NG)
{
NG = 0.5 * (LG + (N / LG));
printf("%.2lf %.3lf\n", N, NG);
}
printf("\nThe square root of %.2lf is %.3lf\n", N, NG);
}
should not the NG - LG <= epsilon become true after the difference is less then 0.005?
Code:
ssma-imac:ENG-3211 ssma$ ./hw_4_1
Please enter the number you wish to find the square root: 4
4.00 2.500
4.00 2.050
4.00 2.001
4.00 2.000
4.00 2.000
4.00 2.000
4.00 2.000
4.00 2.000
...
it will run until i manually break the program. never getting out of the for loop. also what would be a better way of setting LG = NG like i have in my update section for my for?
now my test condition is never coming true:
...
should not the NG - LG <= epsilon become true after the difference is less then 0.005?
Actually your test condition is never becoming false. When the loop is entered the first time NG hasn't been set so its value is arbitrary (gcc ought to warn about this, but it doesn't). On subsequent iterations, because you set LG = NG in the update statement NG - LG = 0 which is always less than epsilon.
Don't evaluate unset variables:
either NG should have a value before entering the loop, or use a do while loop instead
setting LG = NG just before the test makes the test useless, you should put that assignment elsewhere
your test is backwards
you should have a fabs() call in your test
Quote:
side not question. in class the prof. indicated that as long as you have a variable declared you dont need to also declare the pointer value if they are the same. ex:
doubt LG;
*LG = NG
That is what one of his examples had and I asked about it in class. He indicated that this is fine because *LG will point to the memory location of LG, but when i *LG = NG it will change the value stored at NG to the value pointed to by LG. I think i said that semi clear.
That is quite wrong, either your professor doesn't know how to program in C, or you completely misunderstood what he was saying. You must always declare variables before using them, no exceptions. In the example code there, unless there are some other statements assigning to LG the effect of it will to write the value of NG to some random location causing memory corruption and/or crash, except that LG is not being declared as a pointer so it won't even compile...
ntubski, thank you for the reply. I have made some adjustments and I did try a do while loop, but i must of made the similar mistake by setting LG = NG before running the test. In fact i did find the fabs() for my epsilon before you posted. so at least im on the right track with that.
here is what i have that is working, but never leaving the loop:
Code:
do {
NG = 0.5 * (LG + (N / LG));
printf("%.2lf %.3lf\n", N, NG);
LG = NG;
} while (fabs(NG - LG) < epsilon);
printf("\nThe square root of %.2lf is %.3lf\n", N, NG);
}
now if i follow what you said even though NG is now assigned a value, because i am setting the new value of NG before i run my test it will always fail, or never become false. if i leave out the LG = NG in the above do while loop it fails to get past the first loop and prints out the wrong value.
That is where im stuck. do i need additional variables? i am just not seeing how i can update the value of LG with the results of NG if the condition is not met without putting it in the do section of the loop.
Quote:
That is quite wrong, either your professor doesn't know how to program in C, or you completely misunderstood what he was saying.
when i went back and further read his notes he sent out i appear to have been way off base on what he said, or he fixed his notes before e-mailing them to us. either way, thank you again for helping to clear that up.
I am jumping into this conversation late, but perhaps I can be of assistance. You were off to a good start with the original program (post #1). Could we go back to that? Here are the problems that I can see (though there may be others):
It started out using LG, then switches to using *PLG in the loop, but the two were never associated
The test is backwards, as ntubski wrote in post #3
It needs to use fabs(), also noted by ntubski in post #3
Did the instructor say you have to use a pointer for LG? We can make it work with pointers, but it would be pretty simple to do the whole thing without pointers. What is required here?
By the way, there's nothing wrong with using a do-while loop, as in your post #4. We can make that work, but I just wasn't sure why you dropped the original program using the while loop. The for loop, as in post #2, would not be my first (or second) choice for this kind of problem, though I suppose it could be made to work.
now if i follow what you said even though NG is now assigned a value, because i am setting the new value of NG before i run my test it will always fail, or never become false. if i leave out the LG = NG in the above do while loop it fails to get past the first loop and prints out the wrong value.
That is where im stuck. do i need additional variables? i am just not seeing how i can update the value of LG with the results of NG if the condition is not met without putting it in the do section of the loop.
Think about the order of the statements in the loop.
Thank you I figured out today after class and talking with both prof and an other student what i needed to fix. here is the working completed code.
1. to solve my issue of updating LG with the value of NG i used something we went over in class with pointers for swapping values of variables.
2. As I am using a do while loop my test was backwards. I forgot that in a do while will continue until the results is false, not true like in a for and an if statement.
Code:
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<math.h>
//user defined function prototype
void swap(double *a, double *b);
int main(void)
{
double N, NG, LG, *a, *b, epsilon; // setting all variables to type double
epsilon = 0.005; // setting error tolerance to 0.005
LG = 1.0; // setting initial guess value
printf("\nPlease enter the number you wish to find the approximate square root: ");
scanf("%lf",&N); // getting input from user
NG = 0.5 * (LG + (N / LG)); // initialize NG for test in do while loop
do {
swap(&NG, &LG);
NG = 0.5 * (LG + (N / LG));
printf("\n%.2lf %.3lf\n", N, NG);
}
while (fabs(LG - NG) >= epsilon);
printf("\nThe approximate square root of %.2lf is %.3lf\n", N, NG);
}
// using this to swap the values of LG and NG for my do while loop to allow for the update
// of LG from the calculation of NG = foo
void swap(double *a, double *b)
{
double temp;
temp = *a;
*a = *b;
*b = temp;
printf("swap number %.2lf", temp); // used this for testing and troubleshooing logic in do while loop
}
2. As I am using a do while loop my test was backwards. I forgot that in a do while will continue until the results is false, not true like in a for and an if statement.
A for loop also continues until the test is false, the thing that makes a do while different is that it always executes at least one iteration before testing, whereas a for loop might perform zero iterations.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.