136

如何在 C 中处理复数?我看到有一个complex.h头文件,但它并没有给我太多关于如何使用它的信息。如何以有效的方式访问实部和虚部?是否有获取模块和阶段的本机函数?

4

5 回答 5

202

此代码将对您有所帮助,而且不言自明:

#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)

处理复数时要记住的另一个重要点是,函数类似于cos()exp()并且sqrt()必须替换为它们的复数形式,例如ccos(), 。cexp()csqrt()

于 2012-03-25T14:09:21.033 回答
42

-std=c99自 C99 标准( GCC 的选项)以来,复杂类型就在 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_I宏 from complex.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)用于复杂的论证。

要直接访问(读/写)真实的图像部分,您可以使用这个不可移植 的 GCC 扩展

 __real__ a = 1.4;
 __imag__ a = 2.0;
 float b = __real__ a;
于 2011-06-20T23:46:29.537 回答
7

为方便起见,可以包含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;
}
于 2015-11-02T02:09:53.970 回答
4

由于计算负二次根的需要,在数学中引入了复数的概念。复数概念被各种工程领域所采用。

今天,复数被广泛用于先进的工程领域,如物理学、电子学、力学、天文学等……

负平方根示例的实部和虚部:

#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;
}
于 2013-12-24T09:52:16.827 回答
-2

要提取复值表达式 的实部z,请使用符号 as __real__ z。同样,在 上使用__imag__属性z来提取虚部。

例如;

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

r 是复数“z”的实部 i 是复数“z”的虚部

于 2015-05-25T08:11:06.267 回答