如何在 C 中处理复数?

如何使用 C 语言中的复数?我看到有一个 complex.h头文件,但是它没有给我提供太多关于如何使用它的信息。如何有效地访问真实和虚构的部分?是否有获取模块和阶段的本机函数?

218430 次浏览

自 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.h_Complex_I宏:

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

(实际上,(0,-0i)数和 NaNs 在单个半复数中可能存在一些问题)

模块为 cabs(a)/cabsl(c)/cabsf(b); 实部为 creal(a),虚部为 cimag(a)

要直接访问(读/写)实际的一个映像部分,你可以使用这个 无法携带 海湾合作委员会延期:

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

这段代码将会帮助你,而且它是相当自我解释的:

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

与:

得到真实的部分(对于浮点 crealf(z1),对于长双 creall(z1))

获取虚部(对于 float cimagf(z1),对于 long double cimagl(z1))

在处理复数时,另一个需要记住的重点是,像 cos()exp()sqrt()这样的函数必须被它们的复数形式所替代,例如 ccos()cexp()csqrt()

从计算负二次根的需要出发,在数学中引入了复数的概念。复数概念被各种工程领域广泛采用。

今天,复数在物理、电子、力学、天文学等高级工程领域得到了广泛的应用。

负平方根的实部和虚部:

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

要提取复值表达式 z的实部,可以使用表示法 __real__ z。 类似地,使用 z上的 __imag__属性提取虚部。

例如:

__complex__ float z;
float r;
float i;
r = __real__ z;
i = __imag__ z;

R 是复数“ z”的实部 I 是复数“ z”的虚部

为了方便起见,可以包含用于类型生成宏的 tgmath.h库。它为所有类型的变量创建与 double 版本相同的函数名。例如,它定义了一个扩展到 sqrtf()sqrt()sqrtl()函数的 sqrt()宏,这取决于所提供的参数的类型。

所以不需要为不同类型的变量记住对应的函数名!

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