Was using a method from the MathNet Library and tried applying its Cubic root finding function, but it outputs incredibly long decimals, and rounding doesn't seem to affect them.
public static (Complex, Complex, Complex) FindCubic(double a, double b, double c, double d)
{
double num = b * b - 3.0 * a * c;
double num2 = 2.0 * b * b * b - 9.0 * a * b * c + 27.0 * a * a * d;
double num3 = -1.0 / (3.0 * a);
if ((num2 * num2 - 4.0 * num * num * num) / (-27.0 * a * a) == 0.0)
{
if (num == 0.0)
{
Complex complex = new Complex(num3 * b, 0.0);
return (complex, complex, complex);
}
Complex complex2 = new Complex((9.0 * a * d - b * c) / (2.0 * num), 0.0);
Complex item = new Complex((4.0 * a * b * c - 9.0 * a * a * d - b * b * b) / (a * num), 0.0);
return (complex2, complex2, item);
}
(Complex, Complex, Complex) tuple = ((num == 0.0) ? new Complex(num2, 0.0).CubicRoots() : ((num2 + Complex.Sqrt(num2 * num2 - 4.0 * num * num * num)) / 2.0).CubicRoots());
return (num3 * (b + tuple.Item1 + num / tuple.Item1), num3 * (b + tuple.Item2 + num / tuple.Item2), num3 * (b + tuple.Item3 + num / tuple.Item3));
}
The code above works fine, but really not sure how to shorten the decimals in the results. For example if the output should be (-1, 0) in theory (and it does display so on most calculators), it instead displays (-1, -2.0354088784794536E-16), which is close to 0, and should be displayed as 0.
Round(num3, 0) * (b + new Complex (Round(tuple.Item1.Real, 0), Round(tuple.Item1.Imaginary, 0)) + num / tuple.Item1)
The rounding code in question since you can't directly round complex numbers.
Solved in comment: Forgot about floating point inaccuracy.
There's nothing particularly wrong with the answer you get. Remember that floating point calculations are inherently approximate. Indeed, the distance between (1,0)
and (1, -2.0354088784794536E-16)
is less than 1ulp. What most calculators do to avoid such unpleasant outputs is to calculate with a couple extra digits and round the result to fit the display.
As for your rounding code, it rounds intermediary results rather than the final answer:
Round(num3, 0) * (b + new Complex (Round(tuple.Item1.Real, 0), Round(tuple.Item1.Imaginary, 0)) + num / tuple.Item1)
What you want instead is something like this:
int digits = 8;
Complex tmp = num3 * (b + tuple.Item1 + num / tuple.Item1);
tmp = new Complex(Round(tmp.Real, digits), Round(tmp.Imaginary, digits));
Though the best practice would be to let the rounding happen in the formatting routine.