Bootstrap

C++求解一元三次方程的根(实虚皆取)

方法:

一元三次方程求根可以采用卡尔丹公式盛金公式,此处采用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;
}

参考:

1、C++求解一元三次方程的实根

;