问题三十七:C++怎么解一元四次方程?(2)——怎么解一元三次方程

37.2 怎么解一元三次方程?

用“盛金公式”求解:

----------------------------------------------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;
        }
    }

 

你可能感兴趣的:(ray,trace,C++,computer,graphics)