`_Imaginary_I` 매크로 — 허수 단위 상수
_Imaginary_I 매크로 — 허수 단위 상수
복소수나 허수 타입을 다룰 때, 허수부의 음의 영(negative zero) 부호를 그대로 살려야 하는 경우가 있어요. _Complex_I로는 그 부호가 보존되지 않을 수 있다고 했죠. 이때 쓸 수 있는 정밀한 도구가 바로 _Imaginary_I예요.
본문
_Imaginary_I 매크로는 허수 단위의 값을 가진 const float _Imaginary 타입의 값으로 확장돼요.
#define _Imaginary_I /* unspecified */ // (since C99)
C에서 순수 허수 숫자를 지원하는 것과 마찬가지로, 이 매크로는 허수 숫자가 지원될 때에만 정의돼요.
지원 여부
__STDC_IEC_559_COMPLEX__를 정의한 컴파일러라도 허수 숫자를 지원할 의무는 없어요. POSIX는 허수 숫자 지원 여부를 확인하려면 _Imaginary_I 매크로가 정의되어 있는지 검사하라고 권장해요.
- C99~C11 이전: 허수 숫자는
__STDC_IEC_559_COMPLEX__가 정의되어 있으면 지원돼요. - C11부터: 마찬가지로
__STDC_IEC_559_COMPLEX__정의 여부로 판단해요.
Notes
이 매크로는 복소수를 실수부·허수부로부터 정밀하게 조립하는 방법을 제공해요. 예를 들어
(double complex)((double)x + _Imaginary_I * (double)y)
이런 패턴이에요. 이 패턴은 C11에서 CMPLX 매크로로 표준화됐어요. 대신 _Complex_I를 쓰면, 이 표현식이 허수 위치의 음의 영을 양의 영으로 바꿔도 허용된다는 점을 기억하세요.
예시
_Imaginary_I와 _Complex_I가 무한대와 만날 때 어떻게 다른지 보여주는 코드예요.
#include <stdio.h>
#include <complex.h>
#include <math.h>
int main(void)
{
double complex z1 = 0.0 + INFINITY * _Imaginary_I;
printf("z1 = %.1f%+.1fi\n", creal(z1), cimag(z1));
double complex z2 = 0.0 + INFINITY * _Complex_I;
printf("z2 = %.1f%+.1fi\n", creal(z2), cimag(z2));
}
출력:
z1 = 0.0+Infi
z2 = NaN+Infi
흥미로운 차이가 보여요. _Imaginary_I 쪽은 0.0 * ∞가 실수부에서 그대로 0.0으로 유지되는 반면, _Complex_I를 쓰면 0.0 * ∞가 NaN으로 밀려나 실수부가 NaN이 돼버려요. 순수 허수 계산의 정밀성이 여기서 드러나는 거죠.
표준 참조
- C11: 7.3.1/5
_Imaginary_I(p: 188), G.6/1 (p: 537) - C99: 7.3.1/3
_Imaginary_I(p: 170), G.6/1 (p: 472)
더 알아보기
I매크로가_Complex_I와_Imaginary_I중 무엇으로 확장되는지가 동작의 분기점이에요.- 정밀한 복소수 조립이 필요하면
CMPLX매크로를 살펴보세요. - cppreference의 _Imaginary_I 원문에서 참조 절을 더 확인할 수 있어요.