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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6418807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 08:59:13  来源:igfitidea点击:

How to work with complex numbers in C?

ccomplex-numbers

提问by Charles Brunet

How can I work with complex numbers in C? I see there is a complex.hheader file, but it doesn't give me much information about how to use it. How to access real and imaginary parts in an efficient way? Is there native functions to get module and phase?

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

回答by

This code will help you, and it's fairly self-explanatory:

这段代码将帮助你,它是相当不言自明的:

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

  with:

  和:

creal(z1):get the real part (for float crealf(z1), for long double creall(z1))

creal(z1)获取实部(对于 float crealf(z1),对于 long double creall(z1)

cimag(z1):get the imaginary part (for float cimagf(z1), for long double cimagl(z1))

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

Another important point to remember when working with complex numbers is that functions like cos(), exp()and sqrt()must be replaced with their complex forms, e.g. ccos(), cexp(), csqrt().

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

回答by osgx

Complex types are in the C language since C99 standard (-std=c99option of GCC). Some compilers may implement complex types even in more earlier modes, but this is non-standard and non-portable extension (e.g. IBM XL, GCC, may be intel,... ).

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

You can start from http://en.wikipedia.org/wiki/Complex.h- it gives a description of functions from complex.h

您可以从http://en.wikipedia.org/wiki/Complex.h开始- 它给出了 complex.h 中的函数描述

This manual http://pubs.opengroup.org/onlinepubs/009604499/basedefs/complex.h.htmlalso gives some info about macros.

本手册http://pubs.opengroup.org/onlinepubs/009604499/basedefs/complex.h.html还提供了一些有关宏的信息。

To declare a complex variable, use

要声明复杂变量,请使用

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

or

或者

  float _Complex   b;        // use c*f functions - with f suffix
  long double _Complex c;    // use c*l functions - with l suffix

To give a value into complex, use _Complex_Imacro from complex.h:

要将值赋予复杂,请使用_Complex_I宏 from complex.h

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

(actually there can be some problems here with (0,-0i)numbers and NaNs in single half of complex)

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

Module is cabs(a)/cabsl(c)/cabsf(b); Real part is creal(a), Imaginary is cimag(a). carg(a)is for complex argument.

模块cabs(a)/ cabsl(c)/ cabsf(b); 实部是creal(a),虚部是cimag(a)carg(a)用于复杂的论证。

To directly access (read/write) real an imag part you may use this unportableGCC-extension:

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

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

回答by complex

Complex.h

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

回答by an offer can't refuse

For convenience, one may include tgmath.hlibrary for the type generate macros. It creates the same function name as the double version for all type of variable. For example, For example, it defines a sqrt()macro that expands to the sqrtf(), sqrt(), or sqrtl()function, depending on the type of argument provided.

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

So one don't need to remember the corresponding function name for different type of variables!

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

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

回答by LXSoft

The notion of complex numbers was introduced in mathematics, from the need of calculating negative quadratic roots. Complex number concept was taken by a variety of engineering fields.

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

Today that complex numbers are widely used in advanced engineering domains such as physics, electronics, mechanics, astronomy, etc...

今天,复数被广泛应用于高级工程领域,如物理学、电子学、力学、天文学等......

Real and imaginary part, of a negative square root example:

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

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

回答by Cyclops

To extract the real part of a complex-valued expression z, use the notation as __real__ z. Similarly, use __imag__attribute on the zto extract the imaginary part.

要提取复数值表达式的实部z,请使用表示法为__real__ z。同样,使用__imag__上的属性z来提取虚部。

For example;

例如;

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

r is the real part of the complex number "z" i is the imaginary part of the complex number "z"

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