Namespaces
Variants

Type-generic math (since C99)

From cppreference.net

헤더 파일 <tgmath.h> <math.h> <complex.h> 헤더 파일을 포함하며, 인수의 타입에 따라 호출할 실수 함수 또는 해당하는 경우 복소수 함수를 결정하는 여러 타입-제네릭 매크로 를 정의합니다.

각 매크로에 대해, 접미사가 없는 <math.h> 함수에서 해당 실제 타입이 double 인 매개변수들은 제네릭 매개변수 로 알려져 있습니다 (예를 들어, pow 의 두 매개변수 모두 제네릭 매개변수이지만, scalbn 의 첫 번째 매개변수만 제네릭 매개변수입니다).

<tgmath.h> 의 매크로가 사용될 때, 제네릭 매개변수에 전달된 인자의 타입에 따라 아래에 설명된 대로 매크로가 선택하는 함수가 결정됩니다. 인자의 타입이 선택된 함수의 매개변수 타입과 호환되지 않는 경우 , 동작은 정의되지 않습니다 (예: 복소수 인자가 실수 전용 <tgmath.h> 매크로에 전달되는 경우: float complex fc ; ceil ( fc ) ; 또는 double complex dc ; double d ; fmax ( dc, d ) ; 는 정의되지 않은 동작의 예시입니다).

참고: 타입-제네릭 매크로는 C99에서 구현 정의 방식으로 구현되었으나, C11 키워드 _Generic 를 사용하면 이러한 매크로를 이식 가능한 방식으로 구현할 수 있습니다.

목차

복소수/실수 타입-제네릭 매크로

실수와 복소수 버전을 모두 갖는 모든 함수에 대해, 다음 중 하나를 호출하는 타입-제네릭 매크로 XXX 가 존재합니다:

  • 실수 함수:
  • float 변형 XXXf
  • double 변형 XXX
  • long double 변형 XXXl
  • 복잡한 함수:
  • float 변형 cXXXf
  • double 변형 cXXX
  • long double 변형 cXXXl

위 규칙에 대한 예외는 아래 표에 나와 있는 fabs 매크로입니다.

호출할 함수는 다음과 같이 결정됩니다:

  • 제네릭 매개변수 인수 중 하나라도 허수인 경우, 각 함수 참조 페이지에서 개별적으로 동작이 명시됩니다 (특히, sin , cos , tan , cosh , sinh , tanh , asin , atan , asinh , 및 atanh 실수 함수를 호출하며, sin , tan , sinh , tanh , asin , atan , asinh , 및 atanh 의 반환 타입은 허수이고, cos cosh 의 반환 타입은 실수입니다).
  • 제네릭 매개변수 인수 중 하나라도 복소수인 경우, 복소수 함수가 호출됩니다. 그렇지 않으면 실수 함수가 호출됩니다.
  • 제네릭 매개변수 인수 중 하나라도 long double 인 경우, long double 변형이 호출됩니다. 그렇지 않고 매개변수 중 하나라도 double 또는 정수형인 경우, double 변형이 호출됩니다. 그렇지 않으면 float 변형이 호출됩니다.

타입-제네릭 매크로는 다음과 같습니다:

타입-제네릭
매크로
실수 함수
변형
복소수 함수
변형
float double long double float double long double
절대값 fabsf fabs fabsl cabsf cabs cabsl
지수 함수 expf exp expl cexpf cexp cexpl
로그 logf log logl clogf clog clogl
거듭제곱 powf pow powl cpowf cpow cpowl
제곱근 sqrtf sqrt sqrtl csqrtf csqrt csqrtl
sin sinf sin sinl csinf csin csinl
코사인 cosf cos cosl ccosf ccos ccosl
탄젠트 tanf tan tanl ctanf ctan ctanl
아크사인 asinf asin asinl casinf casin casinl
acos acosf acos acosl cacosf cacos cacosl
아크탄젠트 atanf atan atanl catanf catan catanl
sinh sinhf sinh sinhl csinhf csinh csinhl
cosh coshf cosh coshl ccoshf ccosh ccoshl
tanh tanhf tanh tanhl ctanhf ctanh ctanhl
asinh asinhf asinh asinhl casinhf casinh casinhl
acosh acoshf acosh acoshl cacoshf cacosh cacoshl
아크 하이퍼볼릭 탄젠트 atanhf atanh atanhl catanhf catanh catanhl

실수 전용 함수

복소수 버전이 존재하지 않는 모든 함수들에 대해, modf 를 제외하고, 실수 함수의 다양한 변형 중 하나를 호출하는 타입-제네릭 매크로 XXX 가 존재합니다:

  • float 변형 XXXf
  • double 변형 XXX
  • long double 변형 XXXl

호출할 함수는 다음과 같이 결정됩니다:

  • 제네릭 매개변수들 중 하나라도 long double 인 경우, long double 변형이 호출됩니다. 그렇지 않고 제네릭 매개변수들 중 하나라도 double 인 경우, double 변형이 호출됩니다. 그렇지 않으면 float 변형이 호출됩니다.
타입-제네릭
매크로
실수 함수
변형들
float double long double
atan2 atan2f atan2 atan2l
cbrt cbrtf cbrt cbrtl
ceil ceilf ceil ceill
copysign copysignf copysign copysignl
오차 함수 erff erf erfl
erfc erfcf erfc erfcl
exp2 exp2f exp2 exp2l
expm1 expm1f expm1 expm1l
fdim fdimf fdim fdiml
floor floorf floor floorl
fma fmaf fma fmal
fmax fmaxf fmax fmaxl
fmin fminf fmin fminl
fmod fmodf fmod fmodl
frexp frexpf frexp frexpl
hypot hypotf hypot hypotl
ilogb ilogbf ilogb ilogbl
ldexp ldexpf ldexp ldexpl
lgamma lgammaf lgamma lgammal
llrint llrintf llrint llrintl
llround llroundf llround llroundl
log10 log10f log10 log10l
log1p log1pf log1p log1pl
log2 log2f log2 log2l
logb logbf logb logbl
lrint lrintf lrint lrintl
lround lroundf lround lroundl
nearbyint nearbyintf nearbyint nearbyintl
nextafter nextafterf nextafter nextafterl
nexttoward nexttowardf nexttoward nexttowardl
나머지 remainderf remainder remainderl
remquo remquof remquo remquol
rint rintf rint rintl
반올림 roundf round roundl
scalbln scalblnf scalbln scalblnl
scalbn scalbnf scalbn scalbnl
tgamma tgammaf tgamma tgammal
trunc truncf trunc truncl

복소수 전용 함수

실수 버전이 없는 모든 복소수 함수에 대해, 복소수 함수의 변형 중 하나를 호출하는 타입-제네릭 매크로 cXXX 가 존재합니다:

호출할 함수는 다음과 같이 결정됩니다:

  • 제네릭 매개변수 중 하나라도 실수, 복소수 또는 허수인 경우, 적절한 복소수 함수가 호출됩니다.
타입-제네릭
매크로
복소수 함수
변형
float double long double
carg cargf carg cargl
conj conjf conj conjl
creal crealf creal creall
cimag cimagf cimag cimagl
cproj cprojf cproj cprojl

예제

#include <stdio.h>
#include <tgmath.h>
int main(void)
{
    int i = 2;
    printf("sqrt(2) = %f\n", sqrt(i)); // 인수 타입은 int, sqrt 호출
    float f = 0.5;
    printf("sin(0.5f) = %f\n", sin(f)); // 인수 타입은 float, sinf 호출
    float complex dc = 1 + 0.5*I;
    float complex z = sqrt(dc); // 인수 타입은 float complex, csqrtf 호출
    printf("sqrt(1 + 0.5i) = %f+%fi\n",
           creal(z),  // 인수 타입은 float complex, crealf 호출
           cimag(z)); // 인수 타입은 float complex, cimagf 호출
}

출력:

sqrt(2) = 1.414214
sin(0.5f) = 0.479426
sqrt(1 + 0.5i) = 1.029086+0.242934i

참고문헌

  • C23 표준 (ISO/IEC 9899:2024):
  • 7.25 Type-generic math <tgmath.h> (p: TBD)
  • C17 표준 (ISO/IEC 9899:2018):
  • 7.25 Type-generic math <tgmath.h> (p: 272-273)
  • C11 표준 (ISO/IEC 9899:2011):
  • 7.25 Type-generic math <tgmath.h> (p: 373-375)
  • C99 표준 (ISO/IEC 9899:1999):
  • 7.22 Type-generic math <tgmath.h> (p: 335-337)