Multiple conditions in while loop

bags

New member
Joined
Mar 26, 2020
Messages
4
Programming Experience
Beginner
Hello guys. I am trying to create a program to estimate the square root of a number, without using the built-in Math. functions. I have a recipe that must be followed, I think you can understand it in the loop. But for some reason it appears that the while loop is getting exited before I get the right answer? The answer needs to be precise up to 0.0001 decimals to the real square root.
PS. I first tried without the bool but did not change anything.

C#:
        static void Main(string[] args)
        {
            double est;
            double n1 = 0.0001;
            double estX;
            double en = 1;
            double to = 2;
            bool status = false;

            start:
            Console.Write("Provide a number: ");
            double x = Convert.ToDouble(Console.ReadLine());

            if (x >= 1)
            {
                est = (en + x) / to; // first estimate
                estX = (est * est);

                while (status == false)
                {
                    if (((x - n1) < estX) && (estX > (x + n1)))
                        status = true;

                    else if (estX > x)
                    {
                        est = (en + est) / to;
                        status = false;
                    }

                    else if (estX < x)
                    {
                        est = (est + x) / to;
                        status = false;
                    }
                    estX = (est * est);
                }

                Console.WriteLine("\nRoot of " + x + " = " + est);
                Console.WriteLine("\nReal Answer: " + Math.Sqrt(x));
                Console.ReadKey();
            }

            else
            {
                Console.WriteLine("\nerror 404");
                Console.ReadKey();
                Console.Clear();
                goto start;
            }             
        }
 
Debug your code. Set a breakpoint at the top and then step through it line by line, examining the state at each step. You can then follow exactly what the code does and see when that differs from what you expect. You may well be able to solve the issue yourself at that stage but, if you can't, at least you can provide us with much more relevant information.

That said, this indicates an issue with your attitude:
I think you can understand it in the loop
Your code doesn't work, yet you're expecting us to work out what you're supposed to be doping from that code that doesn't do it. Do you not see an issue with that? You should be comparing your code to each step of that recipe and confirming that you're actually doing what you're supposed to. You should also be providing us with that recipe so that we can do the same. I doubt that that recipe includes every detail either, so you should be filling in the details yourself first, testing that algorithm manually and only then writing code to implement that detailed algorithm. If the code doesn't work, you should be able to compare it to the algorithm and see exactly where the difference is. If there is no difference then your algorithm is not working and you need to go back and fix that first.
 
Thanks for the tip, I didn't know about debugging breakpoints. Seems like im hitting the points I should, maybe the loop never meet the criteria when I dont get any answers? I do, however, get results for some numbers with my new code.
So, the recipe is like this:
For the number x (user input), we know the answer (root) must be greater than 1, and lower than x.
First we try to estimate the root by checking if the answer is the midpoint between 1 and x (so the first formula is (1+x) / 2)
If the answer squared is bigger than x, we try to find the midpoint between 1 and our answer (so (1+answer) / 2).
If the answer squared is lower than x, we try to find the midpoint between our answer and x (so (answer+x) / 2).
We follow this recipe until our answer squared is close to x by a precision of 0.0001.

So, if I write x = 9, I get the answer 3.
But if I however write x = 16, it wont write out any answers. (squaring 9 only required one iteration thorugh the loop)

I've tried to change all doubles to decimals, without any changes. Im starting to wonder if the recipe itself may be wrong (shouldn't be), or can anyone see any errors in my code?


Here is my new (and hopefully improved) code:
C#:
        static void Main(string[] args)
        {
            double est;
            double n1 = 0.0001;
            double estX;
            double one = 1; // not sure if this is required, but if i just write 1 it will be an int(?)
            double two = 2;

            start:
            Console.Write("Write a number: ");
            double x = (Console.ReadLine());

            if (x >= 1)
            {
                est = (one + x) / two;
                estX = (est * est);
            
                    while (((x - n1) > estX) || (estX > (x + n1))) // if any of these conditions are met, the answer is not precise enough
                    {
                        if (estX > x) // if answer squared is greater than x
                        {
                            est = (one + est) / two;
                        }

                        else if (estX < x) // if answer squared is less than
                        {
                            est = (est + x) / two;
                        }
                        estX = (est * est); // updates estX for each iteration
                    }
                Console.WriteLine("\nRoot of " + x + " = " + est);
                Console.WriteLine("\nReal root (for comparison): " + Math.Sqrt(x));
                Console.ReadKey();
            }

            else
            {
                Console.WriteLine("\nerror 404, try again");
                Console.ReadKey();
                Console.Clear();
                goto start;
            }           
        }
 
But if I however write x = 16, it wont write out any answers.
So, again, step through the code and see whether it does what you expect and, if not, where and how it differs. You must have an expectation of what each line of code does so debug it to see whether it does do it or not. If it doesn't, then you need to figure out why. If it does and it still doesn't produce the desired results then it's your expectations that are at fault, so you need to go back and examine them.
 
The loop is infinite when x = 16. I am sure that my code is following the recipe, so I have mailed the author and asked what is going on.
 
You appear to be correct. I tried implementing that algorithm myself and I got to the point where it was repeating the following three numbers:

3.14285714285714
9.57142857142857
5.28571428571429

I tried with Decimal rather than Double as well and got basically the same three numbers repeating.

By the way, if you want a Double literal then just add at least one decimal place. If you do this:
C#:
var x = 1;
then x will indeed be inferred to be type int. If you do this:
C#:
var x = 1.0;
then x will be inferred to be type double. If you do this:
C#:
var x = 1M;
then x will be inferred to be type decimal. The M suffix stands for "money", indicating that the decimal data type is primarily for financial calculations. There are suffixes for various other types too, e.g. F for float. You can also use the suffix D for double instead of including a decimal place.
 
Last edited:
For the record, here's my implementation:
C#:
using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("Please enter a positive number x:");

            var input = Console.ReadLine();
            double x;

            while (!double.TryParse(input, out x) || x <= 0.0)
            {
                Console.WriteLine("Please enter a positive number x:");

                input = Console.ReadLine();
            }

            var answer = (1.0 + x) / 2.0;
            var answerSquared = answer * answer;

            while (Math.Abs(answerSquared - x) > 0.0001)
            {
                //Console.WriteLine(answer);

                if (answerSquared > x)
                {
                    answer = (1.0 + answer) / 2.0;
                }
                else
                {
                    answer = (answer + x) / 2.0;
                }

                answerSquared = answer * answer;
            }

            Console.WriteLine($"The square root of {x} is {answer}.");
            Console.ReadLine();
        }
    }
}
 
Thank you for usefull tips, and your While-conditions seems to be more "pretty" than mine, might change that in my code!
 
Back
Top Bottom