求解一元二次方程的高精度根(附C/C++代碼)

通過編程解決問題時,通常有“一力降十會”的說法,使用一個強有力的算法所帶來的效果可能比使用十次巧妙的編程技巧更有效

對方程進行求解,有求根公式可得

這樣做真的合理麼?當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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章