命名空間
變體
動作

型別泛型數學 (自 C99 起)

出自 cppreference.com
< c‎ | numeric

標頭檔 <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 巨集(請參見下方表格)。

呼叫何種函數的判定方式如下:

  • 若泛型參數的任一引數為虛數,則行為由各個函數參考頁面單獨指定(特別是 sincostancoshsinhtanhasinatanasinhatanh 會呼叫實數函數;sintansinhtanhasinatanasinhatanh 的回傳型別為虛數,而 coscosh 的回傳型別為實數)。
  • 若泛型參數的任一引數為複數,則呼叫複數函數;否則呼叫實數函數。
  • 若泛型參數的任一引數為 long double,則呼叫 long double 變體。否則,若任一參數為 double 或整數,則呼叫 double 變體。否則,呼叫 float 變體。

型別泛型巨集如下:

型別泛型
巨集
實數函數
變體
複數函數
變體
  float double long double float double long double
fabs fabsf fabs fabsl cabsf cabs cabsl
exp expf exp expl cexpf cexp cexpl
log logf log logl clogf clog clogl
pow powf pow powl cpowf cpow cpowl
sqrt sqrtf sqrt sqrtl csqrtf csqrt csqrtl
sin sinf sin sinl csinf csin csinl
cos cosf cos cosl ccosf ccos ccosl
tan tanf tan tanl ctanf ctan ctanl
asin asinf asin asinl casinf casin casinl
acos acosf acos acosl cacosf cacos cacosl
atan 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
atanh 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
erf 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
remainder remainderf remainder remainderl
remquo remquof remquo remquol
rint rintf rint rintl
round 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)); // argument type is int, calls sqrt
 
    float f = 0.5;
    printf("sin(0.5f) = %f\n", sin(f)); // argument type is float, calls sinf
 
    float complex dc = 1 + 0.5*I;
    float complex z = sqrt(dc); // argument type is float complex, calls csqrtf
    printf("sqrt(1 + 0.5i) = %f+%fi\n",
           creal(z),  // argument type is float complex, calls crealf
           cimag(z)); // argument type is float complex, calls 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 型別泛型數學 <tgmath.h> (p: 待定)
  • C17 標準 (ISO/IEC 9899:2018)
  • 7.25 型別泛型數學 <tgmath.h> (p: 272-273)
  • C11 標準 (ISO/IEC 9899:2011)
  • 7.25 型別泛型數學 <tgmath.h> (p: 373-375)
  • C99 標準 (ISO/IEC 9899:1999)
  • 7.22 型別泛型數學 <tgmath.h> (p: 335-337)
English Deutsch 日本語 中文(简体) 中文(繁體)