通过编程求解一元二次方程的高精度根

通过编程解决问题时,通常有“一力降十会”的说法,使用一个强有力的算法所带来的效果可能比使用十次巧妙的编程技巧更有效

对方程进行求解,有求根公式可得

这样做真的合理么?当b的平方远远大于4ac时将造成数据精度的丢失(当-b+root(或者-b-root)很小的时,将对求根结果的精度造成损失,或者说减法是易失精度的),多次采用这样的方式计算结果将使精度的损失增大

其实,用以下这组公式也能用于求解一元二次方程(可以通过通分和求根公式证明)

这两组解单独采用任何一组解都不能降低精度,但可以通过搭配的方式解决这个矛盾

算法过程如下,当b>0时,使用

当b<0时,使用

当b=0时

 

C++实现过程如下:

//该程序用于求解二次方程组
//作者:cclplus 邮箱:[email protected]
#include<iostream>
#include<cmath>
using namespace std;
long double a, b, c;
long double temp,root,r1,r2;
int main() {
	ios::sync_with_stdio(false);
	bool flag;
	flag = true;
	cout << "该程序用于求一元二次方程ax^2+bx+c=0的解" << endl;
	cout << "请依次输入a b c的值(a不要为0)" << endl;
	cin >> a >> b >> c;
	temp = b * b - 4* a*c;
	root = sqrt(temp);
	if (temp < 0) {
		flag = false;
	}
	else {
		if (b > 0) {
			r1 = 2 * c / (-b - root);
			r2 = (-b - root) / 2 / a;
		}
		else if(b<0){
			r1 = (-b + root) / 2 / a;
			r2 = 2 * c / (-b + root);
		}
		else {
			temp = c / a;
			r1 = sqrt(-temp);
			r2= -sqrt(-temp);	
		}
	}
	if (flag) {
		cout << "一元二次方程的解为:" << endl;
		cout << r1 << " , " << r2 << endl;
	}
	else {
		cout << "一元二次方程无解" << endl;
	}
	return 0;
}

也可以sign函数

新的算法过程如下

新的代码

//该程序用于求解二次方程组
//作者:cclplus 邮箱:[email protected]
#include<iostream>
#include<cmath>
using namespace std;
long double a, b, c;
long double temp,root,r1,r2;
long double sign(long double b) {
	if (b >= 0) {
		return 1;
	}
	else {
		return -1;
	}
}
int main() {
	ios::sync_with_stdio(false);
	bool flag;
	flag = true;
	cout << "该程序用于求一元二次方程ax^2+bx+c=0的解" << endl;
	cout << "请依次输入a b c的值(a不要为0)" << endl;
	cin >> a >> b >> c;
	temp = b * b - 4* a*c;
	root = sqrt(temp);
	if (temp < 0) {
		flag = false;
	}
	else {
		temp = -b - sign(b)*root;
		r1 = 2 * c/temp;
		r2 = temp / 2/a;
	}
	if (flag) {
		cout << "一元二次方程的解为:" << endl;
		cout << r1 << " , " << r2 << endl;
	}
	else {
		cout << "一元二次方程无解" << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37772174/article/details/81211013
今日推荐