C99 标准对复数类型和复数运算的支持

最近写计算程序经常要用到复数运算,以前都是用 gsl 库中对复数运算的支持。这两天看了看C99 标准,发现C99 中对复数运算的支持还是蛮给力的,这里做个总结。C99 中引入了两个关键字 _Complex和 _Imaginary,并且定义了如下的复数类型:

float _Complex
double _Complex
long double _Complex
float _Imaginary
double _Imaginary
long double _Imaginary
这六种复数类型的含义显而易见,这里不多解释。需要特殊指出的是 _Imaginary相关数据类型在当前版本的 gcc 中还没有被支持。因为我现在电脑上没有安装其他的编译器,所以别的编译器能否支持也不清楚。不过 _Imaginary相关数据类型似乎用处不大,至少我没发现什么地方有这个需要。

下面给个简单的程序例子:

#include <stdio.h>

extern double creal(double _Complex);
extern double cimag(double _Complex);
extern double _Complex csqrt(double _Complex);
extern double _Complex csin(double _Complex);

int main(void)
{
    double _Complex a = 1.0 + 2.0 * csqrt(-1);
    double _Complex  b = 5.0 + 4.0 * csqrt(-1);
    printf("a = %f + %fi\n", creal(a), cimag(a));
    printf("b = %f + %fi\n", creal(b), cimag(b));
    a *= b;    printf("a * b = %f + %fi\n", creal(a), cimag(a));
    a = csin(b);    printf("sin(b) = %f + %fi\n", creal(a), cimag(a));
   return 0;
}
计算结果如下:a = 1.000000 + 2.000000i
b = 5.000000 + 4.000000i
a * b = -3.000000 + 14.000000i
sin(b) = -26.186527 + 7.741118i

上面程序中用到了几个函数:

creal() 获得复数的实部
cimag() 获得复数的虚部
csqrt() 计算复数的平方根
csin() 计算复数的sin值

因为程序中没有包含复数支持的头文件,因此需要自己声明这几个函数。我之所以这样做是为了强调 _Complex 是编译器支持的原生类型,不是在头文件中声明的结构体。

C99 标准中之所以使用 _Complex和 _Imaginary而不直接用 complex 和 imaginary 作为关键字,是为了避免与一些现存的C 程序中的变量名发生冲突。如果能够确定自己的代码中没有用到 complex、imaginary 、I 作为变量名,那么可以包含 complex.h 头文件,包含这个头文件后就可以用 complex 代替 _Complex 了。这里需要特别提一句,C99 标准中似乎没有约定单位虚数i 在程序中如何简便的表示。gcc的实现方式是定义了两个宏,_Complex_I和 I 来表示单位虚数 i 。

因此上面的程序可以简化成如下的样子:

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

int main(void)
{
    double _Complex a = 1.0 + 2.0 * I;
    double _Complex  b = 5.0 + 4.0 * I;
    printf("a = %f + %fi\n", creal(a), cimag(a));
    printf("b = %f + %fi\n", creal(b), cimag(b));
    a *= b;    printf("a * b = %f + %fi\n", creal(a), cimag(a));
    a = csin(b);    printf("sin(b) = %f + %fi\n", creal(a), cimag(a));
   return 0;
}

除了这里用到的几个函数之外,gcc 提供的支持复数运算的函数还很多,这里总结如下。
函数名        简介
cacos()        反余弦
casin()        反正弦
catan()        反正切
ccos()        余弦
csin()        正弦
ctan()        正切
cacosh()    反双曲余弦
casinh()    反双曲正弦
catanh()    反双曲正切
ccosh()        双曲余弦
csinh()        双曲正弦
ctanh()        双曲正切
cexp()        指数函数
clog()        对数函数
cpow(x,y)    x 的y 次方
csqrt        平方根
cabs        复数的模
carg        角
conj        共轭
cproj        投影
cimag        取虚部
creal        取实部


你可能感兴趣的:(C99 标准对复数类型和复数运算的支持)