2.2 complex.h を使ってやる場合

変数の宣言は、次のように行う。
  float complex a;
  double complex b;
  long double complex c;
実部、虚部を求める関数として、
単精度 crealf(), cimagf()
倍精度 creal(), cimag()
長倍精度 creall(), cimagl()

がある。 その他に絶対値 cabs(), 共役複素数 conj(), 偏角 carg(), それからもちろん(?) cexp(), csin() などの関数が用意されている。

(システム標準のコンパイラーならば、complex.h のパス名は /usr/include/complex.h であろうから、 一度どういうものがあるか読んでみると良い。)

虚数単位は I という名前で使える。 i は他で使われるだろうから大文字ということらしい。 もし j が使いたければ
#undef I
#define j _Imaginary_I
としなさい、だとか。


/*
 * test-with-complex.h.c
 */

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

int main(void)
{
  double complex a,b,c;
  double re_b, im_b;

  a = 1+2i;

  printf("input Re b and Im b:");
  scanf("%lf%lf", &re_b, &im_b);
  b = re_b + im_b * I;

  c = a + b;
  printf("%f%+fi\n", creal(c), cimag(c));
  return 0;
}


(某月某日) 某学生がはまった落とし穴。 complex double 型の数値を double 型の数値に代入して、 結果がおかしいと悩んでいた (代入の結果は、複素数値の実部になる。 代入直後に結果を表示したりすれば気がついただろうが、 計算の途中に紛れ込んでいたため、発見が遅れた。)。 これくらいはコンパイラーが警告して欲しいような気がするが、 もともと
  int i;
  double x;
  ...
  i = x;
のように int 型変数に double 型の数値を代入できたりする (結果は原点に向かっての切り捨てになった -- いつもこうなるかどうかは知らない) 言語仕様なので、そう思うのは筋違いなのかもしれない。注意しないと。

桂田 祐史
2018-06-19