C에서 복소수로 작업하는 방법?


122

C에서 복소수로 작업하려면 어떻게해야합니까? 나는이 볼 complex.h헤더 파일은, 그러나 그것은 나에게 그것을 사용하는 방법에 대한 많은 정보를 제공하지 않습니다. 효율적인 방식으로 실제 및 가상 부품에 액세스하는 방법은 무엇입니까? 모듈 및 단계를 가져 오는 기본 함수가 있습니까?


16
Python 코드에 바인딩하는 것이 더 쉽기 때문에 C ++ 대신 C를 사용하고 있습니다.
Charles Brunet 2011 년

답변:


186

이 코드는 도움이 될 것이며 상당히 자명합니다.

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


12
이것은 무엇입니까 double complex? 이것은 언어 확장입니까, 아니면 매크로 마법입니까?
Calmarius

@Calmarius complex는 표준 c99 유형입니다 (GCC의 내부에서는 실제로 _Complex 유형의 별칭입니다).
Snaipe

9
@Snaipe : complex유형이 아닙니다. 로 확장되는 매크로이며 _Complex유형 지정자 이지만 그 자체로는 유형이 아닙니다. 복잡한 유형은 float _Complex, double _Complex하고 long double _Complex.
Keith Thompson

3
GCC뿐만 아니라 _Complex는 유형 지정자이고 complex.h에는 _Complex로 확장되는 복잡한 매크로가 있다고 표준에 정의되어 있습니다. _Bool과 stdbool.h도 마찬가지입니다.
jv110

40

복잡한 유형은 C99 표준 ( -std=c99GCC의 옵션) 이후 C 언어로되어 있습니다 . 일부 컴파일러는 더 이전 모드에서도 복잡한 유형을 구현할 수 있지만 이는 비표준 및 이식 불가능한 확장입니다 (예 : IBM XL, GCC, 인텔, ...).

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에서 매크로를 사용하십시오 complex.h.

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

(실제로 여기에 몇 가지 문제가있을 수 있습니다. (0,-0i) 숫자와 NaN이 하나의 복잡한 부분에 )

모듈은 cabs(a)/ cabsl(c)/ cabsf(b); 진짜 부분은 creal(a), Imaginary는cimag(a) 입니다. carg(a)복잡한 논쟁을위한 것입니다.

실제 imag 부분에 직접 액세스 (읽기 / 쓰기)하려면이 휴대용 GCC 확장을 사용할 수 있습니다 .

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

1
거의 모든 복잡한 함수는 효율적인 방식으로 내장 함수로 컴파일러에 의해 구현됩니다. 최신 컴파일러를 사용하고 0이 아닌 수준의 최적화를 제공하십시오.
osgx

3
참고로 OP는 Python 바인딩을 언급하므로 Python으로 작업 할 때 C89를 고수하려고합니다 (나머지 Python의 코드는 C89이기 때문에 확장 기능이 Windows에서 실행되기를 원하면 일반적으로 MVSC로 컴파일됩니다. C89). 그래도 꼭 필요한지 모르겠습니다.
detly

1
표현식 (complex float) { r, i }은 숫자의 개별 부분을 독립적으로 설정하는 데 사용할 수도 있습니다 (예를 들어 허수 부분이 NAN 인 동안 실수 부분이 INF가되도록 허용). 실제로 이식 가능한지 확실하지 않지만 GCC 관련 키워드를 피합니다.
cleong

2
C99에서 Complex 지원은 선택 사항입니다. 컴파일러는 __STDC_NO_COMPLEX__. 그러나 실제로는 주요 컴파일러에서 구현됩니다.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

1
Jasen, N1256 draft open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf#page=182 "7.3 복잡한 산술 <complex.h>"의 182 페이지를 확인하십시오 . 이러한 키워드는 수작업으로 복잡한 것을 구현하는 기존의 c (C90) 프로그램을 깨지 않기 위해 C99에서 선택되었을 것입니다. <complex.h>가 포함되면 complex매크로로 정의되고 _Complex. Derek M. Jones의 "The New C Standard : An Economic and Cultural Commentary"(2008) 페이지 500 "복잡한 유형" people.ece.cornell.edu/land/courses/ece4760/…
osgx

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

4

편의를 위해 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;
}

2

복소수의 개념은 음의 2 차근을 계산할 필요가 있기 때문에 수학에서 도입되었습니다. 복소수 개념은 다양한 공학 분야에서 취해졌습니다.

오늘날 복소수는 물리학, 전자, 기계, 천문학 등과 같은 고급 엔지니어링 영역에서 널리 사용됩니다.

음의 제곱근 예제의 실수 부와 허수 부 :

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

-1

복소수 표현식의 실수 부분을 추출하려면 z표기법을 __real__ z. 마찬가지로 __imag__속성을z 을 사용하여 허수 부를 추출합니다.

예를 들면 다음과 같습니다.

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

r은 복소수 "z"의 실수 부분입니다. i는 복소수 "z"의 허수 부분입니다.


2
이들은 gcc 관련 확장입니다. 또 다른 대답은 이미, 그리고 언급 허용 대답을 표준 C.에서이 작업을 수행하는 방법을 이미
키이스 톰슨에게
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.