3

I have constructed an extremely simple, yet fully-functioning and quite helpful, WinForms C# application that solves for the real roots of a quadratic equation.

Here is my current programming logic:

   string noDivideByZero = "Enter an a value that isn't 0";
    txtSolution1.Text = noDivideByZero;
    txtSolution2.Text = noDivideByZero;

    decimal aValue = nmcA.Value;
    decimal bValue = nmcB.Value;
    decimal cValue = nmcC.Value;

    decimal solution1, solution2;
    string solution1String, solution2String;

    //Quadratic Formula: x = (-b +- sqrt(b^2 - 4ac)) / 2a

    //Calculate discriminant
    decimal insideSquareRoot = (bValue * bValue) - 4 * aValue * cValue;

    if (insideSquareRoot < 0)
    {
        //No real solution
        solution1String = "No real solutions!";
        solution2String = "No real solutions!";

        txtSolution1.Text = solution1String;
        txtSolution2.Text = solution2String;
    }
    else if (insideSquareRoot == 0)
    {
        //One real solution
        decimal sqrtOneSolution = (decimal)Math.Sqrt((double)insideSquareRoot);
        solution1 = (-bValue + sqrtOneSolution) / (2 * aValue);
        solution2String = "No real solution!";

        txtSolution1.Text = solution1.ToString();
        txtSolution2.Text = solution2String;
    }
    else if (insideSquareRoot > 0)
    {
        //Two real solutions
        decimal sqrtTwoSolutions = (decimal)Math.Sqrt((double)insideSquareRoot);
        solution1 = (-bValue + sqrtTwoSolutions) / (2 * aValue);
        solution2 = (-bValue - sqrtTwoSolutions) / (2 * aValue);

        txtSolution1.Text = solution1.ToString();
        txtSolution2.Text = solution2.ToString();
    }

txtSolution1 and txtSolution2 are the text boxes which aren't allowed to receive input, but output the results of the calculation

nmcA, nmcB and nmcC are NumericUpDown controls which are used for a, b and c value input by the end user

OK, so, I was hoping to take it a step further, and possibly solve for imaginary values as well. Considering I have the conditionals already set up, I would need to account for imaginary values only when the discriminant is equal to 0 or less than 0.

However, I can't think of a good way to approach this. The complex solutions occur when one attempts to take the square root of a negative number, leading to the is appearing everywhere. i = sqroot(-1) and i^2 = -1.

Does anyone know how to approach this problem, or if it is just not worth the time?

EDIT

With a little more Googling, I have found that it is possible with C# 4.0 (or .NET 4.0 I'm not sure which) there is built-in complex number support in System.Numerics.Complex. I'm checking this out now.

kiamlaluno
  • 24,790
  • 16
  • 70
  • 85
Qcom
  • 16,009
  • 27
  • 82
  • 112
  • 1
    I have no idea why you're converting everything to decimal, also you are taking the square root of zero for no apparent reason (it's always zero and contributes nothing to the answer), and in that case `solution2String` should be "repeated root", not "No real solution". – Ben Voigt Nov 08 '10 at 23:04
  • Whoops, I forgot about the repeated root, it should say `multiplicity of 0` instead, or something like that. Thanks for pointing that out! Also, decimal gives higher accuracy, does it not? – Qcom Nov 08 '10 at 23:05
  • 2
    You're doing the math in `double`, and then converting to `decimal` afterward. So no, you aren't getting higher accuracy, you're just slowing down the works. – Ben Voigt Nov 08 '10 at 23:19
  • 1
    I believe that the .Net 4 framework is only supported by the CLR 4 (hence C# 4) language. See http://stackoverflow.com/questions/148833/will-net-4-0-include-a-new-clr-or-keep-with-version-2-0 – Peter M Nov 08 '10 at 23:26
  • @Ben, ok, I'll remedy that and update the code in a bit. @Peter thanks for the reference there. – Qcom Nov 08 '10 at 23:37

2 Answers2

4

e.g. you are trying to calculate

(-b + sqrt(inside)) / (2*a)

Math.Sqrt doesn't know about imaginary numbers, so it croaks if inside < 0. But we can always multiply by 1 without changing the answer. Note that i2 = -1. And -1 * i2 = 1. So let's multiply by -1 * i2 and simplify:

(-b + sqrt(inside * -1 * i**2)) / (2*a)
(-b + sqrt(-inside) * sqrt(i**2)) / (2*a)
(-b + sqrt(-inside) * i) / (2*a)
-b/(2*a) + sqrt(-inside)/(2*a) * i

So the following C# code:

solution1String = (-b/(2*a)).ToString() +
                      " + " + (Math.Sqrt(-inside)/(2*a)).ToString() + " i";
Ben Voigt
  • 260,885
  • 36
  • 380
  • 671
0

So what is the problem that you think you might have? You are already checking for imaginery results. Just calculate accordingly - eg. perform the square root but of a positive value, and keep track of the real and imaginery parts.

winwaed
  • 7,355
  • 6
  • 30
  • 78