如何使用C中的复数?

Cha*_*net 117 c complex-numbers

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

小智 181

这段代码对你有帮助,而且相当不言自明:

#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;
}
Run Code Online (Sandbox Code Playgroud)

  有:

creal(z1):得到真正的部分(浮动crealf(z1),长双creall(z1))

cimag(z1):得到想象的部分(浮动cimagf(z1),长双cimagl(z1))

另外要记住很重要的一点,当使用复数的工作是一样的功能cos(),exp()并且sqrt()必须与他们复杂的形式,例如更换ccos(),cexp(),csqrt().

  • 什么是"双重复合体"?这是语言扩展还是一些宏观魔术? (10认同)
  • @Snaipe:`complex`不是一种类型.它是一个扩展为`_Complex`的宏,它是一个类型*说明符*,但不是一个类型本身.复杂类型是`float _Complex`,`double _Complex`和`long double _Complex`. (7认同)
  • 不仅仅是GCC,它在标准中定义为_Complex 是一个类型说明符,complex.h 有一个扩展为_Complex 的复杂宏。_Bool 和 stdbool.h 也是如此。 (4认同)

osg*_*sgx 40

自C99标准(-std=c99GCC选项)以来,复杂类型在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
Run Code Online (Sandbox Code Playgroud)

要么

  float _Complex   b;        // use c*f functions - with f suffix
  long double _Complex c;    // use c*l functions - with l suffix
Run Code Online (Sandbox Code Playgroud)

要将值赋予复杂,请使用以下_Complex_Icomplex.h:

  float _Complex d = 2.0f + 2.0f*_Complex_I;
Run Code Online (Sandbox Code Playgroud)

(实际上这里可能存在一些问题,(0,-0i)数字和NaN在复杂的一半中)

模块是cabs(a)/ cabsl(c)/ cabsf(b); 真正的部分是creal(a),Imaginary是cimag(a).carg(a)是复杂的论点.

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

 __real__ a = 1.4;
 __imag__ a = 2.0;
 float b = __real__ a;
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,因为OP提到了Python绑定,在使用Python时我试图坚持使用C89(因为Python的其余代码是C89,如果你想让你的扩展在Windows上运行,它通常用MVSC编译,这仅限于C89).我不知道这是绝对必要的. (3认同)
  • 请注意,复杂支持在C99中是可选的:如果编译器定义了`__STDC_NO_COMPLEX__`,编译器可能根本就没有它.然而,在实践中,它是在主要编译器上实现的. (2认同)

小智 9

Complex.h

#include <stdio.h>      /* Standard Library of Input and Output */
#include <complex.h>    /* Standart 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));
}
Run Code Online (Sandbox Code Playgroud)


an *_*use 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;
}
Run Code Online (Sandbox Code Playgroud)