求解复系数一元二次方程(两种方法)
- 求解复系数一元二次方程(使用c语言)
- 求解复系数一元二次方程(使用Cpp)
求解复系数一元二次方程(使用c语言)
鼓励大家完全用C语言的知识,求系数为复数的一元二次方程的解:a*x2+bx+c=0;
即使a,b,c都是(r+yi)形式的复数,那么经典的求根公式也是成立的。
要求:
1、输入三个系数的实部和虚部,输出两个解(可能相同,也可能不同)。
2、两个解不相同时,需先输出虚部为正的解。
3、对虚部为负的解,输出形式因如样例1; 对虚部为0的解,输出形式因如样例2.
4、输出保留两位小数
提示:
1、方程可以用求根公式求解。
2、需考虑当判别式为负实数时的情况。
样例1输入三个复数的系数,a,b,c,(每个系数有实部和虚部两个值):
1 1 //a的实部是1,虚部也是1,即a=1+1i,以下同理
1 1
1 1
输出:
(-0.50+0.87i) //方程的解用(r+yi)形式表示。以下同理
(-0.50-0.87i)
样例2输入:
1 0
-1 -1
0 0
输出:
(1.00+1.00i)
(0.00+0.00i)
提示:当输出(r+yi)时可以:
当y是正数的时候,可以用 printf("(%.2lf+%.2lfi)",r,y); 这样的形式来表示。
当y是负数的时候,可以用 printf("(%.2lf-%.2lfi)",r,-y); 这样的形式来表示。
逻辑
#include<stdio.h>
#include<math.h>
//熟识复数的四则运算和开方运算; complex复数;
//复数加法:
void Cadd(double r1, double r2, double i1, double i2,
double *r, double *i){
*r = r1 + r2;
*i = i1 + i2;
}
//复数减法:
void Csub(double r1, double r2, double i1, double i2,
double *r, double *i){
*r = r1 - r2;
*i = i1 - i2;
}
//复数乘法:
void Cmul(double r1, double r2, double i1, double i2,
double *r, double *i){
*r = r1*r2 - i1*i2;
*i = r1*i2 + i1*r2;
}
//复数除法:
void Cdiv(double r1, double r2, double i1, double i2,
double *r, double *i){
double norm = r2*r2 + i2*i2; //模长norm;
*r = (r1*r2 + i1*i2) / norm;
*i = (i1*r2 - r1*i2) / norm;
}
//复数开方:
void Csqrt(double r, double i, double *sqrt_r, double *sqrt_i){
double norm = sqrt(r*r + i*i);
double theta = atan2(i,r);
*sqrt_r = sqrt(norm) * cos(theta/2);
*sqrt_i = sqrt(norm) * sin(theta/2);
}
//printing func:
void printing(double r, double i){
if(i >= 0){ printf("(%.2lf+%.2lfi)", r, i); }
else { printf("(%.2lf-%.2lfi)", r, -i); }
}
int main()
{
/* 输入三个系数的实部和虚部: */
double a_r, a_i, b_r, b_i, c_r, c_i;
scanf("%lf %lf", &a_r, &a_i);
scanf("%lf %lf", &b_r, &b_i);
scanf("%lf %lf", &c_r, &c_i);
/* 判别式计算-discriminant: */
double disc_r, disc_i;
Cmul(b_r, b_r, b_i, b_i, &disc_r, &disc_i); //b*b;
//4ac:
double tr, ti; //temp;
Cmul(a_r, c_r, a_i, c_i, &tr, &ti); //ac;
Cmul(4, tr, 0, ti, &tr, &ti); //4ac;
//b*b-4ac;
Csub(disc_r, tr, disc_i, ti, &disc_r, &disc_i);
/* 判别式开方 */
double sqrt_r, sqrt_i;
Csqrt(disc_r, disc_i, &sqrt_r, &sqrt_i);
/* 计算两个解的实部虚部 */
double x1_r, x1_i, x2_r, x2_i;
//1:(-b+ )/2a;
Csub(-b_r, sqrt_r, -b_i, sqrt_i, &x1_r, &x1_i);
Cdiv(x1_r, 2*a_r, x1_i, 2*a_i, &x1_r, &x1_i);
//2:(-b- )/2a;
Csub(-b_r, -sqrt_r, -b_i, -sqrt_i, &x2_r, &x2_i);
Cdiv(x2_r, 2*a_r, x2_i, 2*a_i, &x2_r, &x2_i);
/* print */
if( x1_i > x2_i ){
printing(x1_r, x1_i);
printf("\n");
printing(x2_r, x2_i);
}
else{
printing(x2_r, x2_i);
printf("\n");
printing(x1_r, x1_i);
}
return 0;
}
求解复系数一元二次方程(使用Cpp)
求系数为复数的一元二次方程的解,本题有后缀代码:
要求:
1、输入三个系数的实部和虚部,输出两个解(可能相同,也可能不同)。
2、两个解不同时,需先输出虚部为正的解。
3、对虚部为负的解,输出形式因如样例1; 对虚部为0的解,输出形式因如样例2.
提示:
1、方程可以用求根公式求解。
2、需考虑当判别式为负实数时的情况。
样例1输入:
1 1
1 1
1 1
输出:
(-0.5+0.866025i)
(-0.5-0.866025i)
样例2输入:
1 0
-1 -1
0 0
输出:
(1+1i)
(0+0i)
//使用Cpp;
//3.12:求解复系数一元二次方程(有后缀)
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
class Cmycomplex{
private:
double realp, imagp;
public:
Cmycomplex(double r=0, double i=0) : realp(r), imagp(i){}
Cmycomplex sqrt(){
double norm = std::sqrt( realp*realp + imagp*imagp );
double theta = atan2(imagp, realp);
return Cmycomplex(
std::sqrt(norm) * cos(theta/2),
std::sqrt(norm) * sin(theta/2)
);
}
double gety(){
return imagp;
}
//遇到题目限定输出问题, 通义给出版本;
void Show(){
// 定义一个小阈值用于判断是否接近0
const double epsilon = 1e-10;
// 如果实部和虚部的绝对值都小于epsilon,则认为它们是0
if (fabs(realp) < epsilon && fabs(imagp) < epsilon) {
cout << "(0+0i)" << endl;
} else if (fabs(imagp) < epsilon) { // 如果仅虚部接近0
cout << "(" << (fabs(realp) < epsilon ? 0 : realp) << "+0i)" << endl;
} else {
// 正常情况下的输出
cout << "(" << (fabs(realp) < epsilon ? 0 : realp) << (imagp >= 0 ? "+" : "") << (fabs(imagp) < epsilon ? 0 : imagp) << "i)" << endl;
}
}
//mine
/*****
* void Show(){
* //当实部和虚部均为0时, 输出 (0+0i);
* if(realp == 0 && imagp == 0){
* cout << "(0+0i)" << endl;
* }
*
* //当仅虚部为0时, 输出 (实部+0i);
* else if(imagp == 0){
* cout << "(" << realp << "+0i)" << endl;
* }
*
* //正常输出;
* else{
* cout << "(" << realp << (imagp >= 0 ? "+" : "") << imagp << "i)" << endl;
* }
* }
*****/
/* 运算: */
//*:
Cmycomplex operator* (const Cmycomplex &other){
return Cmycomplex(
realp*other.realp - imagp*other.imagp,
realp*other.imagp + imagp*other.realp
);
}
friend Cmycomplex operator* (int value, const Cmycomplex &complex);
//-:
Cmycomplex operator- (const Cmycomplex &other){
return Cmycomplex(
realp - other.realp,
imagp - other.imagp
);
}
friend Cmycomplex operator- (double value, const Cmycomplex &complex);
// /:
Cmycomplex operator/ (const Cmycomplex &other){
double norm = other.realp*other.realp + other.imagp*other.imagp;
return Cmycomplex(
(realp*other.realp + imagp*other.imagp)/norm,
(imagp*other.realp - realp*other.imagp)/norm
);
}
friend Cmycomplex operator/ (double value, const Cmycomplex &complex);
//+:
Cmycomplex operator+ (const Cmycomplex &other){
return Cmycomplex(
realp + other.realp,
imagp + other.imagp
);
}
friend Cmycomplex operator+ (double value, const Cmycomplex &complex);
};
//friend func:
Cmycomplex operator* (int value, const Cmycomplex &complex){
return Cmycomplex(
value * complex.realp,
value * complex.imagp
);
}
Cmycomplex operator- (double value, const Cmycomplex &complex){
return Cmycomplex(
value - complex.realp,
0 - complex.imagp
);
}
Cmycomplex operator/ (double value, const Cmycomplex &complex){
double norm = complex.realp*complex.realp + complex.imagp*complex.imagp;
return Cmycomplex(
(value*complex.realp) / norm,
(0 - value*complex.imagp) / norm
);
}
Cmycomplex operator+ (double value, const Cmycomplex &complex){
return Cmycomplex(
value + complex.realp,
complex.imagp
);
}
//StudybarCommentBegin
int main()
{
double x1, x2, x3, y1, y2, y3;
cin >> x1 >> y1;
cin >> x2 >> y2;
cin >> x3 >> y3;
Cmycomplex a(x1, y1), b(x2, y2), c(x3, y3), z, t1, t2;
z=b*b-4*a*c;
t1=((-1)*b+z.sqrt())/(2*a); //z.sqrt()为求复数z的平方根,这里的2*a涉及操作符重载,且友元重载。
t2=((-1)*b-z.sqrt())/2.0/a; //这里涉及到除法的重载
if(t1.gety()>t2.gety()) //gety()为得到虚部值
{
t1.Show();
t2.Show();
}
else
{
t2.Show();
t1.Show();
}
return 0;
}
//StudybarCommentEnd