web-dev-qa-db-fra.com

Comment travailler avec des nombres complexes en C?

Comment puis-je travailler avec des nombres complexes en C? Je vois qu'il existe un fichier d'en-tête complex.h, mais il ne me donne pas beaucoup d'informations sur son utilisation. Comment accéder aux pièces réelles et imaginaires de manière efficace? Existe-t-il des fonctions natives pour obtenir le module et la phase?

114
Charles Brunet

Ce code va vous aider, et c'est assez explicite:

#include <stdio.h>      /* Standard Library of Input and Output */
#include <complex.h>    /* Standard Library of Complex Numbers */

int main() {

    double complex z1 = 1.0 + 3.0 * I;
    double complex z2 = 1.0 - 4.0 * I;

    printf("Working with complex numbers:\n\v");

    printf("Starting values: Z1 = %.2f + %.2fi\tZ2 = %.2f %+.2fi\n", creal(z1), cimag(z1), creal(z2), cimag(z2));

    double complex sum = z1 + z2;
    printf("The sum: Z1 + Z2 = %.2f %+.2fi\n", creal(sum), cimag(sum));

    double complex difference = z1 - z2;
    printf("The difference: Z1 - Z2 = %.2f %+.2fi\n", creal(difference), cimag(difference));

    double complex product = z1 * z2;
    printf("The product: Z1 x Z2 = %.2f %+.2fi\n", creal(product), cimag(product));

    double complex quotient = z1 / z2;
    printf("The quotient: Z1 / Z2 = %.2f %+.2fi\n", creal(quotient), cimag(quotient));

    double complex conjugate = conj(z1);
    printf("The conjugate of Z1 = %.2f %+.2fi\n", creal(conjugate), cimag(conjugate));

    return 0;
}

avec:

creal(z1): récupère la partie réelle (pour float crealf(z1), pour un long double creall(z1))

cimag(z1): récupère la partie imaginaire (pour float cimagf(z1), pour un long double cimagl(z1))

Un autre point important à retenir lorsque vous travaillez avec des nombres complexes est que les fonctions telles que cos(), exp() et sqrt() doivent être remplacées par leurs formes complexes, par exemple. ccos(), cexp(), csqrt().

176
user870774

Les types complexes sont en langage C depuis le standard C99 (option -std=c99 de GCC). Certains compilateurs peuvent implémenter des types complexes même dans des modes plus anciens, mais il s’agit d’une extension non standard et non portable (par exemple, IBM XL, GCC, peut être intel, ...).

Vous pouvez commencer à partir de http://en.wikipedia.org/wiki/Complex.h - il donne une description des fonctions de complex.h

Ce manuel http://pubs.opengroup.org/onlinepubs/009604499/basedefs/complex.h.html donne également des informations sur les macros.

Pour déclarer une variable complexe, utilisez

  double _Complex  a;        // use c* functions without suffix

ou

  float _Complex   b;        // use c*f functions - with f suffix
  long double _Complex c;    // use c*l functions - with l suffix

Pour donner une valeur en complexe, utilisez la macro _Complex_I de complex.h:

  float _Complex d = 2.0f + 2.0f*_Complex_I;

(en fait, il peut y avoir des problèmes avec (0,-0i) nombres et NaN dans la moitié simple du complexe)

Le module est cabs(a)/cabsl(c)/cabsf(b); La partie réelle est creal(a), Imaginary est cimag(a). carg(a) est pour l'argument complexe.

Pour accéder directement (en lecture/écriture) à une image réelle, vous pouvez utiliser cet élément unportable extension GCC :

 __real__ a = 1.4;
 __imag__ a = 2.0;
 float b = __real__ a;
40
osgx

Complex.h

#include <stdio.h>      /* Standard Library of Input and Output */
#include <complex.h>    /* Standart Library of Complex Numbers */

int main() 
{
    double complex z1 = 1.0 + 3.0 * I;
    double complex z2 = 1.0 - 4.0 * I;

    printf("Working with complex numbers:\n\v");

    printf("Starting values: Z1 = %.2f + %.2fi\tZ2 = %.2f %+.2fi\n", 
           creal(z1), 
           cimag(z1), 
           creal(z2), 
           cimag(z2));

    double complex sum = z1 + z2;
    printf("The sum: Z1 + Z2 = %.2f %+.2fi\n", creal(sum), cimag(sum));
}
8
complex

Pour plus de commodité, on peut inclure la bibliothèque tgmath.h pour les macros de type génération. Il crée le même nom de fonction que la version double pour tous les types de variables. Par exemple, Par exemple, il définit une macro sqrt() qui passe à la fonction sqrtf(), sqrt() ou sqrtl(), en fonction du type d'argument fourni.

Il n'est donc pas nécessaire de retenir le nom de la fonction correspondante pour différents types de variables!

#include <stdio.h>
#include <tgmath.h>//for the type generate macros. 
#include <complex.h>//for easier declare complex variables and complex unit I

int main(void)
{
    double complex z1=1./4.*M_PI+1./4.*M_PI*I;//M_PI is just pi=3.1415...
    double complex z2, z3, z4, z5; 

    z2=exp(z1);
    z3=sin(z1);
    z4=sqrt(z1);
    z5=log(z1);

    printf("exp(z1)=%lf + %lf I\n", creal(z2),cimag(z2));
    printf("sin(z1)=%lf + %lf I\n", creal(z3),cimag(z3));
    printf("sqrt(z1)=%lf + %lf I\n", creal(z4),cimag(z4));
    printf("log(z1)=%lf + %lf I\n", creal(z5),cimag(z5));

    return 0;
}
3

La notion de nombres complexes a été introduite en mathématiques, à partir du besoin de calculer des racines quadratiques négatives. Le concept de nombre complexe a été adopté par une variété de domaines techniques.

Aujourd'hui, ces nombres complexes sont largement utilisés dans des domaines d'ingénierie avancés tels que la physique, l'électronique, la mécanique, l'astronomie, etc.

partie réelle et imaginaire d'un exemple de racine carrée négative:

#include <stdio.h>   
#include <complex.h>

int main() 
{
    int negNum;

    printf("Calculate negative square roots:\n"
           "Enter negative number:");

    scanf("%d", &negNum);

    double complex negSqrt = csqrt(negNum);

    double pReal = creal(negSqrt);
    double pImag = cimag(negSqrt);

    printf("\nReal part %f, imaginary part %f"
           ", for negative square root.(%d)",
           pReal, pImag, negNum);

    return 0;
}
2
LXSoft