Question Trouble Implementing Quadratic Formula

itsamemario

New member
Joined
Jun 17, 2017
Messages
3
Programming Experience
Beginner
Hi everyone!


First of all, I need the mathematicians out there!


I have been working on a calculator / math quiz program in C#, and currently I am trying to allow the user to have quadratic equations (ax²+bx+c = 0) solved automatically with
the quadratic formula by inserting the values for a, b, and c.


It is already working, except for that one part that isn't.
Have an example:


Console.WriteLine("xPlus equals" + (-quadEq_b + (double)Math.Sqrt(discriminant) / 2*quadEq_a + "."));


I have been comparing the results doing the same math in my "real" calculator and the results don't match. (but the decimals do, for some reason) It seems, however, I have
found what is causing the results to be wrong, but don't know how to fix it. I tried to remove "/ 2*quadEq_a" and then compared the results again doing the same thing on my
real life calculator, and voilà, the results did match.


I suppose I am ignoring some rule to be followed if you want to divide a number by a multiplication (like in this case "2*quadEq_a")


Putting it in brackets, like "/ (2*quadEq_a")" didn't change anything, either.


I'd appreciate it if someone can help me with this :) Below you find all the code relevant for this problem.


Mario
// Quadratic Formula values


double quadEq_b;
double quadEq_c;
double quadEq_a;
double discriminant;


QuadraticEquationSolver:
Console.WriteLine("A quadratic equation in its normal form looks like this: \n ax^2+bx+c = 0 \n In order to solve for x, you need to declare the values for a, b, and c \n 
These values are then plugged into the quadratic formula. \n Please insert a value for a:");
quadEq_a = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Please insert a value for b:");
quadEq_b = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Please insert a value for c:");
quadEq_c = Convert.ToDouble(Console.ReadLine());
discriminant = (double)Math.Pow(quadEq_b, 2) - 4 * quadEq_a * quadEq_c;
if (discriminant < 0)
{
Console.WriteLine("The discriminant is negative, therefore no solution for x exists. \n Press any key to return to the Main Menu.");
Console.ReadKey();
goto Start;


}
if (discriminant == 0)
{
Console.WriteLine("The discriminant equals zero, therefore one solution for x exists.");
Console.ReadKey();
Console.WriteLine(discriminant);
Console.ReadKey();
goto QuadFormOneSolution;
}
if (discriminant > 0)
{
Console.WriteLine("The discriminant is positive, therefore two solutions for x exist.");
Console.ReadKey();
Console.WriteLine(discriminant);
Console.ReadKey();
goto QuadFormTwoSolutions;
}


QuadFormOneSolution:
Console.WriteLine("x equals" + -quadEq_b + (double)Math.Sqrt(discriminant) / 2*quadEq_a + ".");
Console.ReadKey();


QuadFormTwoSolutions:
Console.WriteLine("xPlus equals" + (-quadEq_b + (double)Math.Sqrt(discriminant) / 2*quadEq_a + "."));
Console.WriteLine("xMinus equals" + (-quadEq_b - (double)Math.Sqrt(discriminant) / 2*quadEq_a + "."));
Console.ReadKey();
 
Last edited by a moderator:
Before getting into the math issue, I see a glaring overall problem with your code here you should consider correcting: the use of goto. Get rid of the goto's and I'll be happy to help with the rest of the issues.
 
// Quadratic Formula values

double quadEq_b;
double quadEq_c;
double quadEq_a;
double discriminant;

Console.WriteLine("A quadratic equation in its normal form looks like this: \n ax^2+bx+c = 0 \n In order to solve for x, you need to declare the values for a, b, and c \n These values are then plugged into the quadratic formula. \n Please insert a value for a:");

quadEq_a = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Please insert a value for b:");
quadEq_b = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Please insert a value for c:");
quadEq_c = Convert.ToDouble(Console.ReadLine());
discriminant = (double)Math.Pow(quadEq_b, 2) - 4 * quadEq_a * quadEq_c;

if (discriminant < 0)
{
    Console.WriteLine("The discriminant is negative, therefore no solution for x exists. \n Press any key.");
    Console.ReadKey();
}
if (discriminant == 0)
{
    Console.WriteLine("The discriminant equals zero, therefore one solution for x exists.");
    Console.ReadKey();
    Console.WriteLine(discriminant);
    Console.ReadKey();
    Console.WriteLine("x equals" + -quadEq_b + (double)Math.Sqrt(discriminant) / 2 * quadEq_a + ".");
    Console.ReadKey();
}
if (discriminant > 0)
{
    Console.WriteLine("The discriminant is positive, therefore two solutions for x exist.");
    Console.ReadKey();
    Console.WriteLine(discriminant);
    Console.ReadKey();
    Console.WriteLine("xPlus equals" + (-quadEq_b + (double)Math.Sqrt(discriminant) / 2 * quadEq_a + "."));
    Console.WriteLine("xMinus equals" + (-quadEq_b - (double)Math.Sqrt(discriminant) / 2 * quadEq_a + "."));
    Console.ReadKey();
}
 
Last edited by a moderator:
Your quadratic equation itself looks off, you're parenthesis are positioned off so it looks like you're taking the opposite of b and adding it to the square root of the discriminant divided by 2, then multiplying it all by a.
The actual formula is:
double Answer = (-b + Math.Sqrt(discriminant)) / (2 * a);


Here's my take on it, here are my inputs:
C#:
No solution:
a = 1
b = -3
c = 6

One solution:
a = 1
b = -6
c = 9
 x = 3

Two solutions:
a = 1
b = -2
c = -8
 x = -2, 4
And my program:
using System;

namespace QuadraticEquation {
    public class Program {
        private static bool m_ExitProgram = false;

        static void Main(string[] args) {
            Console.WriteLine("A quadratic equation in its normal form looks like this:\n ax^2+bx+c = 0 \nIn order to solve for x, you need to declare the values for a, b, and c\nThese values are then plugged into the quadratic formula.\n");

            while (!m_ExitProgram) {
                double quadEq_a;
                double quadEq_b;
                double quadEq_c;

                InputValue UserInput;

                //Get value for a
                UserInput = GetUserInput("Value for a: ");
                if (!UserInput.ExitProgram) {
                    quadEq_a = UserInput.InputVal;

                    //Get value for b
                    UserInput = GetUserInput("Value for b: ");
                    if (!UserInput.ExitProgram) {
                        quadEq_b = UserInput.InputVal;

                        //Get value for c
                        UserInput = GetUserInput("Value for c: ");
                        if (!UserInput.ExitProgram) {
                            quadEq_c = UserInput.InputVal;

                            Console.WriteLine();

                            //Calculate the actual equation
                            CalculateQuadratic(quadEq_a, quadEq_b, quadEq_c);

                            //Prompt to run again
                            Console.Write("\nRun again (Y/N): ");
                            string RunAgain = Console.ReadLine();
                            if (!(RunAgain.Length > 0 && char.ToLower(RunAgain[0]) == 'y')) {
                                //First char is not a Y or y, exit program
                                m_ExitProgram = true;
                            } else {
                                Console.WriteLine();
                            }
                        } else {
                            //User inputted an X or x, exit program
                            m_ExitProgram = true;
                        }
                    } else {
                        //User inputted an X or x, exit program
                        m_ExitProgram = true;
                    }
                } else {
                    //User inputted an X or x, exit program
                    m_ExitProgram = true;
                }
            }
        }

        private static void CalculateQuadratic(double a, double b, double c) {
            double discriminant = Math.Pow(b, 2) - (4 * a * c);

            Console.Write("Discriminant: {0}", discriminant);

            if (discriminant < 0) {
                Console.WriteLine(", no solution for x exists.");
            } else if (discriminant == 0) {
                Console.WriteLine(", one solution for x exists:");
                double Answer = (-b + Math.Sqrt(discriminant)) / (2 * a);
                
                Console.WriteLine("x equals {0}", Answer);
            } else {
                Console.WriteLine(", two solutions for x exist.");
                double AnswerPlus = (-b + Math.Sqrt(discriminant)) / (2 * a);
                double AnswerMinus = (-b - Math.Sqrt(discriminant)) / (2 * a);

                Console.WriteLine("x equals {0}, {1}", AnswerMinus, AnswerPlus);
            }
        }

        private static InputValue GetUserInput(string prompt) {
            bool ExitLoop = false;
            bool ExitProgram = false;

            string InputValStr;
            double InputValDbl = 0.0;

            //Loop until value double is entered or an X/x to indicate exiting
            while (!ExitLoop) {
                Console.Write(prompt);

                InputValStr = Console.ReadLine();

                //Check for an X/x value
                if (InputValStr.Length > 0 && char.ToLower(InputValStr[0]) != 'x') {
                    //Exit the loop if the input is numeric (double)
                    ExitLoop = double.TryParse(InputValStr, out InputValDbl);
                } else {
                    //An X/x was found, break the loop & exit the program
                    ExitLoop = true;
                    ExitProgram = true;
                }
            }

            return new QuadraticEquation.InputValue(InputValDbl, ExitProgram);
        }
    }

    public class InputValue {
        //This just holds the value of input and whether the program is to exit or not
        private double m_InputVal;
        private bool m_ExitProgram;

        public InputValue() {
            m_InputVal = 0.0;
            m_ExitProgram = false;
        }

        public InputValue(double InputVal, bool ExitProgram) {
            m_InputVal = InputVal;
            m_ExitProgram = ExitProgram;
        }

        public double InputVal { get { return m_InputVal; } }
        public bool ExitProgram { get { return m_ExitProgram; } }
    }
}
 
Aaaah, looking at your solution, I was confused at first. I compared (doubleAnswer = (-b + Math.Sqrt(discriminant)) / (2 * a)) to what I wrote and then didn't spot the difference at first. I didn't take into account to also form the brackets/parentheses(?) around the nominator too, not the just the denominator (2*a). I then plugged in the abc values you posted and now the solutions match.

Thanks a bunch for taking your time and effort, man! Also, exploring the code you provided is really fun and a great way to improve my C# skills :D

A few more things though:

- I can't figure out how to use this xcode tag to make code appear like in the editor. If I try to use it it says something about brush and in the end it doesn't work.

- In my math quiz, I use the Random class to randomize the math problems each time. The problem is it only generates these random numbers once per session, meaning if i repeat the quiz before closing the program, the exact same numbers appear again. I am sure there must be a way to have it generate new random numbers every time without having to restart the program.

- As you can tell by the name of the ints, I am also trying to allow the user to choose difficulty levels which affects the number range, how many "tries" the "player" has, and I also wanna create a time limit for each math problem to be solved (like, say 20 secs).

- Not knowing how to implement tries, I have worked around the problem by simply directing them to a different place in code with goto (like if they fail to answer MultiNormal01_3tries for example, instead of getting gotod to
MultiNormal02_3tries, they'd be directed to MultiNormal02_2tries) and continue on till they have run out of lives.



Random NumberGen = new Random();

//Multiplication integers
int numMulti_easy_2tries_01__1 = NumberGen.Next(5, 9);
int numMulti_easy_2tries_01__2 = NumberGen.Next(7, 11);
int numMulti_easy_2tries_02__1 = NumberGen.Next(5, 9);
int numMulti_easy_2tries_02__2 = NumberGen.Next(7, 11);
int numMulti_normal_3tries_01__1 = NumberGen.Next(6, 13);
int numMulti_normal_3tries_01__2 = NumberGen.Next(7, 14);
int numMulti_normal_3tries_02__1 = NumberGen.Next(6, 13);
int numMulti_normal_3tries_02__2 = NumberGen.Next(7, 14);



Multiplication_Menu:




                Console.WriteLine("Please choose a difficulty setting: \n 1) 8-Year-Old \n 2) Easy \n 3) Normal \n 4) Hard \n 5) Expert \n 0) Return to Main Menu");
                int multi_difchoice_answer = Convert.ToInt32(Console.ReadLine());
                if (multi_difchoice_answer == 1)
                {
                    Console.WriteLine("You are starting off with 2 lives. Press any key to begin. Good Luck!");
                    Console.ReadKey();
                    goto Multiplication_8yo_2tries_01;
                }
                if (multi_difchoice_answer == 2)
                {
                Console.WriteLine("You are starting off with 2 lives. Press any key to begin. Good Luck!");
                Console.ReadKey();
                goto Multiplication_Easy_2tries_01;
                }
                if (multi_difchoice_answer == 3)
                {
                    Console.WriteLine("You are starting off with 3 lives. Press any key to begin. Good Luck!");
                    Console.ReadKey();
                    goto Multiplication_Normal_3tries_01;
                }
                if (multi_difchoice_answer == 4)
                {
                    goto Sorry;
                }
                if (multi_difchoice_answer == 5)
                {
                    goto Sorry;
                }
                if (multi_difchoice_answer == 0)
                {
                    goto Start;
                }
                if (multi_difchoice_answer < 0)
                {
                    goto InvalidEntry;
                }
                if (multi_difchoice_answer > 5)
                {
                    goto InvalidEntry;
                }



Multiplication_Normal_3tries_01:
            Console.WriteLine("What is " + numMulti_normal_3tries_01__1 + " times " + numMulti_normal_3tries_01__2 + "?");
            int result_multinormal_3tries_01 = Convert.ToInt32(Console.ReadLine());
            if (result_multinormal_3tries_01 == numMulti_normal_3tries_01__1 * numMulti_normal_3tries_01__2)
            {


                goto Multiplication_Normal_3tries_02;
            }
            else
            {


                Console.WriteLine("Are you even trying?");
                goto GAMEOVER;


            }
Multiplication_Normal_3tries_02:
            Console.WriteLine("What is " + numMulti_normal_3tries_02__1 + " times " + numMulti_normal_3tries_02__2 + "?");
            int result_multinormal_3tries_02 = Convert.ToInt32(Console.ReadLine());
            if (result_multinormal_3tries_02 == numMulti_normal_3tries_02__1 * numMulti_normal_3tries_02__2)
            {


                goto Multiplication_Normal_3tries_01;
            }
            else
            {


                Console.WriteLine("Are you even trying?");
                goto GAMEOVER;


            }
 
Last edited by a moderator:
To use the xcode tag, it's simply [xcode=c#]Your code here[/xcode]

As for the code, I simply use a couple of loops and make the appropriate sub/function calls as needed, absolutely NO need to use GoTo anywhere.
I did not account for certain number of tries or anything like that in my code, but given the loops all use a boolean variable to know when to exit you could add an integer variable to count each time an answer has been given and increment it as needed, then either the loop has an additional check of the counter to know when to break out of it or you can simply add an if statement to check the counter above or equal to a value and change the boolean variable to a True and the loop will exit.
 
Back
Top Bottom