方法:
一元三次方程求根可以采用卡尔丹公式和盛金公式,此处采用c++语言基于盛金公式求解,亲测ok!!!!!!
代码
#include <iostream>
#include <complex>
#include <cmath>
#include <iomanip>
using namespace std;
typedef std::complex<double> DComplex;
inline DComplex polinom_3(DComplex x, double a, double b, double c,double d)
{
//Horner's scheme for a*x*x*x + b*x*x + c*x + d;
return x * (x * (a*x + b) + c) + d;
}
DComplex* solve_cubic_equation(double a, double b, double c, double d) {
double A=b*b-3*a*c;
double B=b*c-9*a*d;
double C=c*c-3*b*d;
double f=B*B-4*A*C;
double i_value;
double Y1,Y2;
DComplex* retval = new DComplex[4];
if (fabs(A)<1e-6 && fabs(B)<1e-6)//公式1 共三个相同的实根
{
retval[0]=-b/(3*a);
retval[1]=-b/(3*a);
retval[2]=-b/(3*a);
}
else if (fabs(f)<1e-6) //公式3 三个实根,其中两个相同
{
double K=B/A;
retval[0]=-b/a+K;
retval[1]=-K/2;
retval[2]=-K/2;
}
else if (f>1e-6) //公式2
{
Y1=A*b+3*a*(-B+sqrt(f))/2;
Y2=A*b+3*a*(-B-sqrt(f))/2;
double Y1_value=(Y1/fabs(Y1))*pow((double)fabs(Y1),1.0/3);
double Y2_value=(Y2/fabs(Y2))*pow((double)fabs(Y2),1.0/3);
retval[0]=(-b-Y1_value-Y2_value)/(3*a);
retval[1].real((-b+0.5*(Y1_value+Y2_value))/(3*a));
retval[1].imag(sqrt(3.0)/2*(Y1_value-Y2_value)/(3*a));
retval[2]=std::conj(retval[1]);
}
else if (f<-1e-6) //公式4
{
double T=(2*A*b-3*a*B)/(2*A*sqrt(A));
double S=acos(T);
retval[0]=(-b-2*sqrt(A)*cos(S/3))/(3*a);
retval[1]=(-b+sqrt(A)*(cos(S/3)+sqrt(3.0)*sin(S/3)))/(3*a);
retval[2]=(-b+sqrt(A)*(cos(S/3)-sqrt(3.0)*sin(S/3)))/(3*a);
}
return retval;
}
int main()
{
std::cout << std::fixed << std::setprecision(8);
double a, b, c, d;
while(true)
{
// read coefficients of an algebric equation of 3th order (-1000 for exiting the application)
//a*x^3 + b*x^2 +c*x + d =0
std::cout << "--------------------------------------------" << std::endl;
std::cout<<" a*x^3 + b*x^2 + c*x + d = 0 "<< std::endl;
std::cout << "--------------------------------------------" << std::endl;
std::cout << "a = "; std::cin >> a; if(-1000.0==a) break;
std::cout << "b = "; std::cin >> b; if(-1000.0==b) break;
std::cout << "c = "; std::cin >> c; if(-1000.0==c) break;
std::cout << "d = "; std::cin >> d; if(-1000.0==d) break;
std::cout << std::endl;
// solve the algebric equation of 4th order and print the results
std::complex<double>* solutions = solve_cubic_equation(a, b, c, d);
// print the results
std::cout << "x1 = " << (solutions[0].real()>=0. ? " " : "") << solutions[0].real(); if(solutions[0].imag()!=0.0) std::cout << " + i * " << solutions[0].imag(); std::cout << std::endl;
std::cout << "x2 = " << (solutions[1].real()>=0. ? " " : "") << solutions[1].real(); if(solutions[1].imag()!=0.0) std::cout << " - i * " << -solutions[1].imag(); std::cout << std::endl;
std::cout << "x3 = " << (solutions[2].real()>=0. ? " " : "") << solutions[2].real(); if(solutions[2].imag()!=0.0) std::cout << " + i * " << solutions[2].imag(); std::cout << std::endl;
// control / test
std::cout << std::endl;
std::cout << polinom_3(solutions[0], a, b, c, d) << std::endl;
std::cout << polinom_3(solutions[1], a, b, c, d) << std::endl;
std::cout << polinom_3(solutions[2], a, b, c, d) << std::endl;
delete[] solutions;
std::cout << std::endl;
std::cout << "Do you want to continue? (y/n)" << std::endl;
char answer;
std::cin >> answer;
if(answer != 'y' && answer != 'Y')
break;
std::cout << std::endl;
}
return 0;
}