用“盛金公式”求解:
----------------------------------------------main.cpp ------------------------------------------
main.cpp
float* roots_cubic_equation(float a, float b, float c, float d) {
//the first element is the number of the real roots, and other elements are the real roots.
//Shengjin's formula
float *roots = new float[4];
if (a == 0) {
roots = roots_quadratic_equation(b, c, d);
}
else {
float A = b*b - 3*a*c;
float B = b*c - 9*a*d;
float C = c*c - 3*b*d;
float deita = B*B - 4*A*C;
if ((A == B) && (A == 0)) {
//the three roots are the same
if (a != 0) {
roots[1] = -b/(3*a);
}
else {
if (b != 0) {
roots[1] = -c/b;
}
else {
if (c != 0) {
roots[1] = -3*d/c;
}
}
}
roots[2] = roots[1];
roots[3] = roots[1];
roots[0] = 3;
}
else if (deita > 0) {
//only one real root
float y1 = A*b + (3*a/2)*(-B + sqrt(deita));
float y2 = A*b + (3*a/2)*(-B - sqrt(deita));
float pow_y1, pow_y2;
if (y1 < 0) {
//for pow(a,b), when b is not int, a should not be negative.
pow_y1 = - pow(-y1, 1.0/3.0);
}
else {
pow_y1 = pow(y1, 1.0/3.0);
}
if (y2 < 0) {
pow_y2 = - pow(-y2, 1.0/3.0);
}
else {
pow_y2 = pow(y2, 1.0/3.0);
}
roots[1] = (-b - pow_y1 - pow_y2) / (3*a);
roots[0] = 1;
}
else if (deita == 0) {
//three real roots and two of them are the same
float K = B/A;
roots[1] = -b/a + K;
roots[2] = -K/2;
roots[3] = -K/2;
roots[0] = 3;
}
else if (deita < 0) {
//three different real roots
float theta = acos((2*A*b-3*a*B) / (2*pow(A, 1.5)));
roots[1] = (-b - 2*sqrt(A)*cos(theta/3)) / (3*a);
roots[2] = (-b + sqrt(A) * (cos(theta/3) + sqrt(3)*sin(theta/3))) / (3*a);
roots[3] = (-b + sqrt(A) * (cos(theta/3) - sqrt(3)*sin(theta/3))) / (3*a);
roots[0] = 3;
}
}
return roots;
}
int main(){
float *r;
r = roots_cubic_equation(1.0, -6.0, 11.0, -6.0);//1,2,3
// r = roots_cubic_equation(1.0, 0.0, -3.0, 2.0);//1,1,-2
// r = roots_cubic_equation(1.0, 4.0, 5.0, 2.0); //-1,-1,-2
// r = roots_cubic_equation(1.0, -3.0, 3.0, -1.0);
for (int i=0; i<(r[0]+1); i++) {
std::cout << "r[" << i << "]=" << r[i] << endl;
}
}