web-dev-qa-db-ja.com

Cで複素数を処理する方法は?

Cで複素数を使用するにはどうすればよいですか? complex.hヘッダーファイルがありますが、使用方法についての情報はあまりありません。効率的な方法で実部と虚部にアクセスする方法は?モジュールとフェーズを取得するネイティブ関数はありますか?

114
Charles Brunet

このコードはあなたを助けます、そしてそれはかなり自明です:

#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;
}

で:

creal(z1)実部を取得します(float crealf(z1)の場合、long double creall(z1)の場合)

cimag(z1)虚数部を取得します(float cimagf(z1)の場合、long double cimagl(z1)の場合)

複素数を扱う際に覚えておくべきもう1つの重要な点は、cos()exp()、およびsqrt()などの関数を、それらの複素数形式で置き換える必要があることです。 ccos()cexp()csqrt()

176
user870774

複合型は、C99標準(GCCの-std=c99オプション)以降のC言語にあります。一部のコンパイラは、以前のモードでも複雑な型を実装する場合がありますが、これは非標準で移植性のない拡張機能です(たとえば、IBM XL、GCC、intelなど)。

http://en.wikipedia.org/wiki/Complex.h から開始できます-complex.hの関数の説明を提供します

このマニュアル http://pubs.opengroup.org/onlinepubs/009604499/basedefs/complex.h.html は、マクロに関する情報も提供します。

複合変数を宣言するには、次を使用します

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

または

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

値を複合体にするには、_Complex_Icomplex.hマクロを使用します。

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

(実際、ここでは(0,-0i)数と複素数の片側半分のNaNにいくつかの問題がある可能性があります)

モジュールはcabs(a)/cabsl(c)/cabsf(b);です。実部はcreal(a)、虚部はcimag(a)です。 carg(a)は複雑な引数用です。

実際のimagパーツに直接アクセス(読み取り/書き込み)するには、これを使用できますunportableGCC-extension

 __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

便宜上、マクロを生成する型にtgmath.hライブラリを含めることができます。すべてのタイプの変数に対して、ダブルバージョンと同じ関数名を作成します。たとえば、たとえば、提供される引数のタイプに応じて、sqrt()sqrtf()、またはsqrt()関数に展開されるsqrtl()マクロを定義します。

したがって、さまざまなタイプの変数に対応する関数名を覚える必要はありません!

#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;
}

複素数の概念は、負の2次根を計算する必要性から数学に導入されました。複素数の概念は、さまざまな工学分野で採用されました。

今日、その複素数は、物理学、電子工学、力学、天文学などの高度な工学分野で広く使用されています...

負の平方根の例の実部と虚部:

#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