【C言語】_Complex キーワードを徹底解説!複素数リテラルとデータ型をマスターしよう


複素数リテラル

C言語では、_Complex キーワードと接尾辞 i を使って、複素数リテラルを直接記述できます。

_Complex z = 3.0 + 4.0i;

この例では、z は実数部が 3.0、虚数部が 4.0 の複素数になります。

複素数データ型

C言語には、複素数専用のデータ型 complex が用意されています。これは、floatdouble のように、組み込みのデータ型です。

complex z;
z = 3.0 + 4.0i;

この例では、zcomplex 型の変数であり、先ほどと同じように 3.0 + 4.0i の複素数で初期化されています。

複素数の演算

C言語では、複素数に対して通常の算術演算子 (+, -, *, /) を使用できます。また、複素数専用の関数もいくつか用意されています。

  • cimag(z): 複素数 z の虚数部を返します。
  • creal(z): 複素数 z の実数部を返します。
  • carg(z): 複素数 z の偏角 (角度) を返します。
  • cabs(z): 複素数 z の絶対値を返します。

complex z1 = 3.0 + 4.0i;
complex z2 = 2.0 - 3.0i;

complex sum = z1 + z2;
complex diff = z1 - z2;
complex product = z1 * z2;
complex quotient = z1 / z2;

printf("合計: %f + %fi\n", creal(sum), cimag(sum));
printf("差: %f + %fi\n", creal(diff), cimag(diff));
printf("積: %f + %fi\n", creal(product), cimag(product));
printf("商: %f + %fi\n", creal(quotient), cimag(quotient));

この例では、2つの複素数 z1z2 を定義し、それらに対して加算、減算、乗算、除算を行い、結果を出力しています。

_Complex キーワードと complex データ型は、C言語で複素数を扱うための強力なツールです。これらの機能を活用することで、電磁気学、信号処理、画像処理など、様々な分野で応用することができます。

  • 複素数の詳細については、数学の教科書や複素数に関する専門書籍などを参照してください。
  • C言語の標準では、_Imaginary キーワードも定義されていますが、これは将来の使用のために予約されており、現在は使用されていません。


複素数リテラルとデータ型の宣言

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

int main() {
  // 複素数リテラル
  _Complex z1 = 3.0 + 4.0i;
  complex z2 = 2.0 - 3.0i;

  // 複素数データ型の変数
  complex z3;

  // 複素数リテラル代入
  z3 = 1.5 + 2.5i;

  printf("z1: %f + %fi\n", creal(z1), cimag(z1));
  printf("z2: %f + %fi\n", creal(z2), cimag(z2));
  printf("z3: %f + %fi\n", creal(z3), cimag(z3));

  return 0;
}

このコードを実行すると、以下の出力が得られます。

z1: 3.000000 + 4.000000i
z2: 2.000000 - 3.000000i
z3: 1.500000 + 2.500000i

複素数の演算

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

int main() {
  complex z1 = 3.0 + 4.0i;
  complex z2 = 2.0 - 3.0i;

  complex sum = z1 + z2;
  complex diff = z1 - z2;
  complex product = z1 * z2;
  complex quotient = z1 / z2;

  printf("合計: %f + %fi\n", creal(sum), cimag(sum));
  printf("差: %f + %fi\n", creal(diff), cimag(diff));
  printf("積: %f + %fi\n", creal(product), cimag(product));
  printf("商: %f + %fi\n", creal(quotient), cimag(quotient));

  return 0;
}
合計: 5.000000 + 1.000000i
差: 1.000000 + 7.000000i
積: -5.000000 + 10.000000i
商: 1.300000 + 0.500000i
#include <stdio.h>
#include <complex.h>

int main() {
  complex z = 3.0 + 4.0i;

  double abs = cabs(z);
  double angle = carg(z);
  double real = creal(z);
  double imag = cimag(z);

  printf("絶対値: %f\n", abs);
  printf("偏角: %f\n", angle);
  printf("実数部: %f\n", real);
  printf("虚数部: %f\n", imag);

  return 0;
}
絶対値: 5.000000
偏角: 1.107192
実数部: 3.000000
虚数部: 4.000000


構造体を使う

_Complex を使う代わりに、以下のように struct を定義して複素数を表現することができます。

typedef struct {
  double real;
  double imag;
} complex_t;

この complex_t 構造体を用いれば、以下のように複素数の変数やリテラルを定義できます。

complex_t z1 = {3.0, 4.0};
complex_t z2 = {2.0, -3.0};

complex_t sum = {z1.real + z2.real, z1.imag + z2.imag};
// ...

また、構造体のメンバに直接アクセスして、複素数の各成分にアクセスすることもできます。

printf("z1 の実数部: %f\n", z1.real);
printf("z2 の虚数部: %f\n", z2.imag);

C99 標準の complex 型を使う

C99 標準では、complex という組み込みのデータ型が導入されています。これは _Complex と同等の機能を提供しますが、より簡潔で分かりやすい表記が可能です。

#include <complex.h>

complex z1 = 3.0 + 4.0i;
complex z2 = 2.0 - 3.0i;

complex sum = z1 + z2;
// ...

complex.h ヘッダーファイルをインクルードすることで、complex 型を使用することができます。

どちらを選ぶべきか

どちらの方法を選ぶかは、状況によって異なります。

  • 簡潔性と互換性を重視する場合は、C99 標準の complex 型を使うのがおすすめです。特に、C99 標準に対応したコンパイラを使用している場合は、complex 型の方が簡潔に記述できます。
  • 可読性とメンテナンス性を重視する場合は、struct を使った方法がおすすめです。構造体名やメンバ名を用いることで、コードの意味がより明確になり、メンテナンスもしやすくなります。

上記以外にも、以下のような代替方法があります。

  • 独自の複素数ライブラリを使う
  • Boost C++ Libraries の complex テンプレートを使う

しかし、これらの方法は、上記で紹介した方法よりも複雑で、学習コストが高くなります。

C言語で _Complex の代替方法としては、主に構造体を使う方法と C99 標準の complex 型を使う方法があります。どちらを選ぶかは、状況や目的に合わせて判断することが重要です。

  • Visual C++ などの一部のコンパイラでは、_Complex をサポートしていない場合があります。そのような場合は、上記の代替方法を使用する必要があります。
  • C++ では、complex 型は標準ライブラリに含まれています。そのため、C++ で複素数を扱う場合は、_Complex を使う必要はありません。