views:

76

answers:

2

OK, so I'm performing an annoying math computation here, trying to solve for one of the cubic roots.

Now, here is my C# code:

public void CubeCalculate()
{
    //Calculate discriminant

    double insideSquareRoot = (18 * cubicAValue * cubicBValue * cubicCValue * cubicDValue) + (-4 * (Math.Pow(cubicBValue, 3) * cubicDValue) + (Math.Pow(cubicBValue, 2) * Math.Pow(cubicCValue, 2)) + (-4 * cubicAValue * Math.Pow(cubicCValue, 3)) + (-27 * Math.Pow(cubicAValue, 2) * Math.Pow(cubicDValue, 2)));

    if (insideSquareRoot < 0)
    {
        //One real solution, two imaginary
        double onecuberootradical1 = (1 / 2) * (((2 * Math.Pow(cubicBValue, 3)) + (-9 * cubicAValue * cubicBValue * cubicCValue) + (27 * Math.Pow(cubicAValue, 2) * cubicDValue)) + (Math.Sqrt(Math.Pow((2 * Math.Pow(cubicBValue, 3)) + (-9 * cubicAValue * cubicBValue * cubicCValue) + (27 * Math.Pow(cubicAValue, 2) * cubicDValue), 2) + (-4 * Math.Pow(Math.Pow(cubicBValue, 2) + (-3 * cubicAValue * cubicCValue), 3)))));
        double onecuberootradical2 = (1 / 2) * (((2 * Math.Pow(cubicBValue, 3)) + (-9 * cubicAValue * cubicBValue * cubicCValue) + (27 * Math.Pow(cubicAValue, 2) * cubicDValue)) - (Math.Sqrt(Math.Pow((2 * Math.Pow(cubicBValue, 3)) + (-9 * cubicAValue * cubicBValue * cubicCValue) + (27 * Math.Pow(cubicAValue, 2) * cubicDValue), 2) + (-4 * Math.Pow(Math.Pow(cubicBValue, 2) + (-3 * cubicAValue * cubicCValue), 3)))));
        x1 = (-cubicBValue / (3 * cubicAValue)) + ((-1 / (3 * cubicAValue)) * (Math.Pow(onecuberootradical1, 1 / 3))) + (-1 / (3 * cubicAValue) * Math.Pow(onecuberootradical2, 1 / 3));
        x2 = double.NaN;
        x3 = double.NaN;
    }

OK, I'm trying to figure out what's going wrong here.

First of all, since this is part of an MVC application, I have made sure my other roots are working properly, so this is purely the fault of the following computation, not a problem from anywhere else.

Now, I've checked many times here and I have not found anything wrong.

You can compare to the proper formula here: alt text

It is the x1 root that I'm trying to replicate here.

Also, if you would like to know the official discriminant form the same Wikiepdia article here it is:

alt text

Do you guys see anything wrong???

+6  A: 

Right here is something obvious:

(1 / 2)

You are performing integer division there when you should be using a floating point number:

(1 / 2.0)

You don't show us the declaration of your cubic*Value variables, so I will assume that those are doubles.

Ed Swangren
OK, thank you, and yes, those are doubles.
BOSS
Thanks for that, now just a question, does everyone number constant have to be specified with a decimal place to let C# know that it is a floating point/double number? Also, this did not fix my problem entirely..
BOSS
@Boss did you also fix the two 1/3 you have?
Rune FS
Yes, every number in those calculations I included above I appended `.0`. Unless that's bad, and I only need to do that for division...
BOSS
The result of a division will be promoted to the highest precision type, so only one needs to be of the two operands need be a floating point number, but it doesn't make a difference is both are.
Ed Swangren
OK, thanks, but for some reason, it doesn't seem to be computing correctly...
BOSS
Whenever you do division, you have to make sure either the numerator or denominator is a `double` (which you can do by using `3.0` or `2.0` instead of `3` or `2`).
Gabe
+1  A: 

This is or should be one of frequently asked question, and the answer is: What Every Computer Scientist Should Know About Floating-Point Arithmetic ( link )

Margus