Resolution d'equations (jusqu'au 3eme degre) + classe pour manipuler les nombres complexes [djgpp]

Description

Voici un petit programme qui résout les équations du premier, deuxième et troisième degré. Une classe pour manier les complexes avec surcharge des opérateurs est également implémentée pour simplifier la résolution des équations du troisième degré.
Je sais bien qu'il y a déjà une classe pour manipuler les complexes en C++, mais je n'aime pas le travail tout fait alors j'en ai refait une.

Source / Exemple :


#include	<conio.h>
#include	<math.h>
#include	<stdio.h>
#include	<stdlib.h>

////////////////////////////////////////////////////////////////////////////////////////////////////

class		ZM_comp
{
		private:

	double	x;
	double	y;

	friend ZM_comp	operator+(const ZM_comp &c);
	friend ZM_comp	operator-(const ZM_comp &c);
	friend ZM_comp	operator+(const ZM_comp &c1,const ZM_comp &c2);
	friend ZM_comp	operator-(const ZM_comp &c1,const ZM_comp &c2);
	friend ZM_comp	operator*(const ZM_comp &c1,const ZM_comp &c2);
	friend ZM_comp	operator/(const ZM_comp &c1,const ZM_comp &c2);

		public:

		ZM_comp(const ZM_comp &c);
		ZM_comp(double a=0,double b=0);

	double	Re();
	double	Im();
	double	Mod();
	double	Arg();
	void	Coord(double a,double b);
	void	Polar(double mod,double arg);
	ZM_comp	Conj();
	ZM_comp	Root(unsigned n,unsigned k);

	bool	operator==(const ZM_comp &c);
	bool	operator!=(const ZM_comp &c);
	bool	operator<=(const ZM_comp &c);
	bool	operator>=(const ZM_comp &c);
	bool	operator<(const ZM_comp &c);
	bool	operator>(const ZM_comp &c);
	ZM_comp	&operator=(const ZM_comp &c);
	ZM_comp	&operator+=(const ZM_comp &c);
	ZM_comp	&operator-=(const ZM_comp &c);
	ZM_comp	&operator*=(const ZM_comp &c);
	ZM_comp	&operator/=(const ZM_comp &c);
};

////////////////////////////////////////////////////////////////////////////////////////////////////

	ZM_comp::ZM_comp(const ZM_comp &c)
{
	x=c.x;
	y=c.y;
}

	ZM_comp::ZM_comp(double a,double b)
{
	x=a;
	y=b;
}

double	ZM_comp::Re()
{
	return x;
}

double	ZM_comp::Im()
{
	return y;
}

double	ZM_comp::Mod()
{
	return hypot(x,y);
}

double	ZM_comp::Arg()
{
	double	arg;
	double	mod;

	mod=hypot(x,y);
	if (mod==0.) return 0.;
	arg=acos(x/mod);
	if (y<0.) arg=2*PI-arg;
	return arg;
}

void	ZM_comp::Coord(double a,double b)
{
	x=a;
	y=b;
}

void	ZM_comp::Polar(double mod,double arg)
{
	x=mod*cos(arg);
	y=mod*sin(arg);
}

ZM_comp	ZM_comp::Conj()
{
	ZM_comp	c(x,-y);
	return c;
}

ZM_comp	ZM_comp::Root(unsigned n,unsigned k)
{
	ZM_comp	c;

	c.Polar(pow(Mod(),1./(double)(n)),(Arg()+2.*(double)(k)*PI)/(double)(n));
	return c;
}

bool	ZM_comp::operator==(const ZM_comp &c)
{
	return (x==c.x)&&(y==c.y);
}

bool	ZM_comp::operator!=(const ZM_comp &c)
{
	return (x!=c.x)||(y!=c.y);
}

bool	ZM_comp::operator<=(const ZM_comp &c)
{
	return (x<=c.x);
}

bool	ZM_comp::operator>=(const ZM_comp &c)
{
	return (x>=c.x);
}

bool	ZM_comp::operator<(const ZM_comp &c)
{
	return (x<c.x);
}

bool	ZM_comp::operator>(const ZM_comp &c)
{
	return (x>c.x);
}

ZM_comp	&ZM_comp::operator=(const ZM_comp &c)
{
	if (&c!=this)
	{
		x=c.x;
		y=c.y;
	}
	return *this;
}

ZM_comp	&ZM_comp::operator+=(const ZM_comp &c)
{
	x+=c.x;
	y+=c.y;
	return *this;
}

ZM_comp	&ZM_comp::operator-=(const ZM_comp &c)
{
	x-=c.x;
	y-=c.y;
	return *this;
}

ZM_comp	&ZM_comp::operator*=(const ZM_comp &c)
{
	double	temp=x*c.y+c.x*y;

	x=x*c.x-y*c.y;
	y=temp;
	return *this;
}

ZM_comp	&ZM_comp::operator/=(const ZM_comp &c)
{
	double	mod=c.x*c.x+c.y*c.y;
	double	temp=(c.x*y-x*c.y)/mod;

	x=(x*c.x+y*c.y)/mod;
	y=temp;
	return *this;
}

ZM_comp	operator+(const ZM_comp &c1,const ZM_comp &c2)
{
	ZM_comp	ret=c1;
	return ret+=c2;
}

ZM_comp	operator-(const ZM_comp &c1,const ZM_comp &c2)
{
	ZM_comp	ret=c1;
	return ret-=c2;
}

ZM_comp	operator-(const ZM_comp &c)
{
	return 0-c;
}

ZM_comp	operator+(const ZM_comp &c)
{
	return 0+c;
}

ZM_comp	operator*(const ZM_comp &c1,const ZM_comp &c2)
{
	ZM_comp	ret=c1;
	return ret*=c2;
}

ZM_comp	operator/(const ZM_comp &c1,const ZM_comp &c2)
{
	ZM_comp	ret=c1;
	return ret/=c2;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

#define	PRECISION	10000

int	resoudre2(ZM_comp a,ZM_comp b,ZM_comp c,ZM_comp* x);
int	resoudre3(ZM_comp a,ZM_comp b,ZM_comp c,ZM_comp d,ZM_comp* x);
int	resoudre4(ZM_comp a,ZM_comp b,ZM_comp c,ZM_comp d,ZM_comp e,ZM_comp* x);

int	main(int argc,char** argv)
{
	int	deg;
	int	i;
	double	coef[4];
	ZM_comp	sol[4];

		// affichage du titre
	printf("RESOLUTION D'EQUATIONS\r\n"
               "ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\r\n");

		// recolte les coefficients de l'equation s'ils
		// sont passes au programme par ligne de commande
	if (argc>1)
	{
		for (deg=0 ; (deg+1<argc)&&(deg<4) ; deg++) sscanf(argv[deg+1],"%lf",coef+deg);
		printf("\r\n");
	}

		// sinon, l'utilisateur entre les coefficients
	else
	{
		printf("\r\n");
		for (i=0 ; i<4 ; i++)
		{
			printf("degr&#8218; %d : ",i);
			scanf("%lf",coef+i);
			if (coef[i]!=0.) deg=i;
		}
		printf("\r\n");
	}

		// si l'utilisateur n'a pas rentre assez de coefficients
	if (deg==0)
	{
		printf("il ne s'agit pas d'une &#8218;quation");
		while (getch()!='\r');
		return 0;
	}

		// affiche l'equation a resoudre
	for (i=0 ; i<=deg ; i++)
	{
			// si le coefficient est nul, autant ne rien noter
		if (coef[deg-i]==0.) continue;

			// si le coefficient est un, autant afficher juste le signe
		if ((fabs(coef[deg-i])==1.)&&(deg-i!=0)) printf("%+1.0f\b",coef[deg-i]);

			// affiche le coefficient, avec une
			// ou zero  decimale selon le besoin
		else printf("%+.*f",(int)ceil(coef[deg-i]-floor(coef[deg-i])),coef[deg-i]);

			// affiche l'exposant
		if (deg-i==1) printf("x");
		else if (deg-i==2) printf("xý");
		else if (deg-i==3) printf("xü");
	}
	printf(" = 0");
	if (coef[deg]>0.) printf("\r ");

		// resolution des equations, a partir d'ici la
		// variable deg contient le nombre de solutions
	printf("\r\n\r\nLes solutions r&#8218;elles et/ou complexes sont :\r\n\r\n");
	if (deg==1) sol[0]=-coef[0]/coef[1];
	else if (deg==2) deg=resoudre2(coef[2],coef[1],coef[0],sol);
	else if (deg==3) deg=resoudre3(coef[3],coef[2],coef[1],coef[0],sol);

		// affichage des solutions
	for (i=0 ; i<deg ; i++)
	{
		printf("\t%.8f",sol[i].Re());
		if (sol[i].Im()!=0) printf(" + %.8fi",sol[i].Im());
		printf("\r\n");
	}

		// attend que enter soit presse puis quitte
	while (getch()!='\r');

	return 0;
}

int	resoudre2(ZM_comp a,ZM_comp b,ZM_comp c,ZM_comp* x)
{
	int	n;
	ZM_comp	delta;

	delta=b*b-4*a*c;

	if (delta==0.) n=1;
	else n=2;

	x[0]=(-b+delta.Root(2,0))/(2*a);
	x[1]=(-b-delta.Root(2,0))/(2*a);

	return n;
}

int	resoudre3(ZM_comp a,ZM_comp b,ZM_comp c,ZM_comp d,ZM_comp* x)
{
	int	n;
	int	i;
	int	i2;
	int	p3;
	ZM_comp	p;
	ZM_comp	q;
	ZM_comp	z[2][3];

	p=(3*a*c-b*b)/(3*a*a);
	q=(2*b*b*b-9*a*b*c+27*a*a*d)/(27*a*a*a);

	resoudre2(1,q,-(p*p*p)/27,x);

	for (i=0 ; i<3 ; i++) z[0][i]=x[0].Root(3,i);
	for (i=0 ; i<3 ; i++) z[1][i]=x[1].Root(3,i);

	n=0;
	p3=(int)((-p.Re()/3)*PRECISION);
	for (i=0 ; i<3 ; i++)
	{
		for (i2=0 ; i2<3 ; i2++)
		{
			if ((int)((z[0][i]*z[1][i2]).Re()*PRECISION)==p3)
			{
				x[n]=z[0][i]+z[1][i2]-b/(3*a);
				x[n].Coord
				(
					x[n].Re(),
					((double)(int)(x[n].Im()*PRECISION))/PRECISION
				);

				if (n==0) n=1;
				else if (n==1)
				{
					if (x[1]!=x[0]) n=2;
				}
				else if (n==2)
				{
					if ((x[2]!=x[0])&&(x[2]!=x[1])) n=3;
				}
			}
		}
	}

	return n;
}

Conclusion :


si vous ne savez pas comment résoudre une équation du 3ème degré, cherchez des informations sur la méthode de cardan sur Google, ce n'est pas si compliqué que ça (mais ça nécessite une connaissance de base des nombres complexes)

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.