복소 거듭제곱: cpow(C99)
복소 거듭제곱: cpow(C99)
실수에서 pow(x, y)가 x의 y승을 구하듯, 복소수에도 거듭제곱을 계산하는 함수가 있어요. 그것이 바로 cpow예요. 복소 지수라서 실수의 경우보다 결과가 더 다양하게 나올 수 있고, 분지 절단을 어떻게 두는지도 중요하죠.
출처: cppreference
본문
시그니처
<complex.h> 헤더에 정의돼 있어요.
| 형태 | 주석 |
|---|---|
float complex cpowf ( float complex x, float complex y ); |
(1) C99부터 |
double complex cpow ( double complex x, double complex y ); |
(2) C99부터 |
long double complex cpowl ( long double complex x, long double complex y ); |
(3) C99부터 |
#define pow(x, y) |
(4) C99부터, <tgmath.h> |
동작 방식
복소 거듭제곱 x^y를 계산해요. 첫 번째 인자 x에 대해서는 음의 실수축을 따라 분지 절단을 둡니다.
(4)의 pow는 타입 제네릭 매크로예요. 어느 한 인자가 long double complex면 cpowl, double complex면 cpow, float complex면 cpowf를 호출해요. 두 인자가 모두 실수나 정수면 대응하는 실수 함수(powl, pow, powf)를 호출하고, 어느 인자가 허수 타입이면 복소 버전을 호출해요.
반환값
오류가 없다면 복소 거듭제곱 x^y를 반환해요. 오류와 특수한 경우는 cexp(y * clog(x))로 구현한 것과 똑같이 처리돼요. 다만 구현이 특수한 경우를 더 신중하게 처리하는 것은 허용됩니다.
예제
여러 가지 복소 거듭제곱을 계산해 보는 코드예요.
#include <stdio.h>
#include <complex.h>
int main(void)
{
double complex z = cpow(1.0+2.0*I, 2);
printf("(1+2i)^2 = %.1f%+.1fi\n", creal(z), cimag(z));
double complex z2 = cpow(-1, 0.5);
printf("(-1+0i)^0.5 = %.1f%+.1fi\n", creal(z2), cimag(z2));
double complex z3 = cpow(conj(-1), 0.5); // other side of the cut
printf("(-1-0i)^0.5 = %.1f%+.1fi\n", creal(z3), cimag(z3));
double complex z4 = cpow(I, I); // i^i = exp(-pi/2)
printf("i^i = %f%+fi\n", creal(z4), cimag(z4));
}
출력:
(1+2i)^2 = -3.0+4.0i
(-1+0i)^0.5 = 0.0+1.0i
(-1-0i)^0.5 = 0.0-1.0i
i^i = 0.207880+0.000000i
여기서 흥미로운 건 마지막 i^i예요. 수학적으로 i^i = e^(i·ln i) = e^(-π/2)라서 실수값인데, 이 코드에서도 허수부 0인 실수로 잘 나오죠. 또 (-1+0i)^0.5와 (-1-0i)^0.5는 분지 절단의 양쪽에 있어서 +i와 -i로 갈리는 것도 볼 수 있어요.
더 알아보기
cexp: 복소 지수 함수.clog: 복소 자연로그(cpow가 내부적으로 의존하는 함수).csqrt: 복소 제곱근.pow,powf,powl: 실수 거듭제곱.