名稱空間
變體
操作

型別通用數學 (自 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 宏(參見下表)。

呼叫的函式確定如下:

  • 如果通用引數的任何引數是虛數,則行為在每個函式參考頁面上單獨指定(特別是,sincostagcoshsinhtanhasinatanasinhatanh 呼叫實數函式,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: TBD)
  • 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)