如何在C语言中处理复数?

如何在C语言中处理复数?,c,complex-numbers,C,Complex Numbers,如何在C语言中处理复数?我看到有一个complex.h头文件,但它没有给我多少关于如何使用它的信息。如何有效地访问实部和虚部?是否有用于获取模块和阶段的本机函数?自C99标准(-std=C99GCC选项)以来,复杂类型使用C语言。有些编译器甚至可以在更早的模式下实现复杂类型,但这是非标准和不可移植的扩展(例如IBM XL、GCC,可能是intel等) 您可以从开始-它给出complex.h中函数的描述 本手册还提供了一些有关宏的信息 要声明复杂变量,请使用 double _Complex

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

自C99标准(
-std=C99
GCC选项)以来,复杂类型使用C语言。有些编译器甚至可以在更早的模式下实现复杂类型,但这是非标准和不可移植的扩展(例如IBM XL、GCC,可能是intel等)

您可以从开始-它给出complex.h中函数的描述

本手册还提供了一些有关宏的信息

要声明复杂变量,请使用

  double _Complex  a;        // use c* functions without suffix

要将值输入复数,请使用
complex.h
中的
\u complex\u I
宏:

  float _Complex d = 2.0f + 2.0f*_Complex_I;
(实际上,
(0,-0i)
复数单半部分中的数字和NaN可能存在一些问题)

模块为
cabs(a)
/
cabsl(c)
/
cabsf(b)
;实部为
creal(a)
,虚部为
cimag(a)
carg(a)
用于复杂参数

要直接访问(读/写)真正的imag部件,您可以使用此不可移植的


这段代码将对您有所帮助,而且它是不言自明的:

#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;
}
#包含/*标准输入输出库*/
#include/*复数标准库*/
int main(){
双复数z1=1.0+3.0*I;
双络合物z2=1.0-4.0*I;
printf(“处理复数:\n\v”);
printf(“起始值:Z1=%.2f+%.2fi\tZ2=%.2f%+.2fi\n”、creal(Z1)、cimag(Z1)、creal(z2)、cimag(z2));
双复和=z1+z2;
printf(“总和:Z1+Z2=%.2f%+.2fi\n”,creal(总和),cimag(总和));
双复差=z1-z2;
printf(“差异:Z1-Z2=%.2f%+.2fi\n”,creal(差异),cimag(差异));
双复积=z1*z2;
printf(“产品:Z1 x Z2=%.2f%+.2fi\n”,creal(产品),cimag(产品));
双复商=z1/z2;
printf(“商:Z1/Z2=%.2f%+.2fi\n”,creal(商),cimag(商));
双复共轭=conj(z1);
printf(“Z1=%.2f%+.2fi\n的共轭体”,creal(共轭体),cimag(共轭体));
返回0;
}
与:

creal(z1)
获取真实部分(对于float
crealf(z1)
,对于长双
creall(z1)

cimag(z1)
获取虚部(对于浮点
cimagf(z1)
,对于长双精度
cimag(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;
}
#包括
#包括
int main()
{
int negNum;
printf(“计算负平方根:\n”
“输入负数:”;
scanf(“%d”和&negNum);
双复数negSqrt=csqrt(negNum);
双前额=creal(负前额);
双pImag=cimag(负SQRT);
printf(“\n实部%f,虚部%f”
,表示负平方根。(%d)“,
pReal、pImag、negNum);
返回0;
}

要提取复数表达式的实部
z
,请使用符号
\uuuuuuuuuuuuuuz
。 同样,使用
z
上的
\uuuu imag\uuuu
属性提取虚部

比如,

__complex__ float z;
float r;
float i;
r = __real__ z;
i = __imag__ z;
r是复数“z”的实部
i是复数“z”的虚部

为了方便起见,可以包括用于生成宏类型的
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;
}
#包括
#包含//以生成宏类型。
#包含//以便于声明复杂变量和复杂单元I
内部主(空)
{
双复数z1=1./4.*M_-PI+1./4.*M_-PI*I;//M_-PI就是PI=3.1415。。。
双络合物z2,z3,z4,z5;
z2=exp(z1);
z3=sin(z1);
z4=sqrt(z1);
z5=对数(z1);
printf(“exp(z1)=%lf+%lfi\n”,creal(z2),cimag(z2));
printf(“sin(z1)=%lf+%lfi\n”,creal(z3),cimag(z3));
printf(“sqrt(z1)=%lf+%lfi\n”,creal(z4),cimag(z4));
printf(“log(z1)=%lf+%lfi\n”,creal(z5),cimag(z5));
返回0;
}

我使用C而不是C++,因为它更容易绑定到我的Python代码。几乎每个复杂的函数都将以编译器的方式有效地实现为内置函数。只需使用现代编译器,并为其提供一些非零级别的优化。仅供参考,因为OP提到了Python绑定,在使用Python时,我尝试使用C89(因为Python的其余代码是C89,如果您希望扩展在Windows上运行,它通常使用MVSC编译,仅限于C89)。但是我不知道这是绝对必要的。表达式
(复数浮点){r,I}
也可以用来独立地设置数字的独立部分(例如,允许实部为INF,而虚部为NAN)。这避免了GCC特定的关键字tho
__complex__ float z;
float r;
float i;
r = __real__ z;
i = __imag__ z;
#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;
}