Type-generic math (Numerics) – C 中文开发手册
Type-generic math (Numerics) - C 中文开发手册
头文件<tgmath.h>包含头文件<math.h>和<complex.h>,并定义了几个类型泛型宏,它们根据参数的类型确定哪些实际的或适用的复杂函数。对于每个宏,参数的相应的实数类型在未被混合的math.h函数中是double的,被称为泛型参数(例如pow的两个参数都是泛型参数,但只有scalbn的第一个参数是泛型参数)。当使用<tgmath.h>宏时,传递给泛型参数的参数类型决定了如下所述由宏选择哪个函数。 如果参数的类型与所选函数的参数类型不兼容,则行为是未定义的(例如,如果将一个复杂参数传递给实数tgmath宏: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 上述规则的一个例外是晶圆厂宏(参见下表)。要调用的函数如下确定:如果通用参数的任何参数都是虚构的,则在每个函数参考页面上分别指定行为(特别是,sin,cos,tag,cosh,sinh,tanh,asin,atan,asinh和atanh称为实函数, sin,tan,sinh,tanh,asin,atan,asinh和atanh的返回类型是虚构的,cos和cosh的返回类型是实数)如果通用参数的任何参数都很复杂,则调用复杂函数,否则调用实函数。 如果通用参数的任何参数是long double,则long double调用该变体。否则,如果任何参数是double或整数,则double调用该变体。否则,float调用变体。类型通用宏如下所示:
Type-generic macro | Real function variants | Complex function variants | ||||
---|---|---|---|---|---|---|
| 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变体。 否则,如果泛型参数的任何参数是双精度型,则调用双精度型。 否则,调用float变量。
Type-generic macro | Real function variants | ||
---|---|---|---|
| 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 complex 变型 cXXXf double complex 变型 cXXX long double complex 变型 cXXXl 要调用的函数如下确定:如果通用参数的任何参数是实数,复数或虚数,则调用相应的复数函数。
Type-generic macro | Complex function variants | ||
---|---|---|---|
| float | double | long double |
carg | cargf | carg | cargl |
conj | conjf | conj | conjl |
creal | crealf | creal | creall |
cimag | cimagf | cimag | cimagl |
cproj | cprojf | cproj | cprojl |
例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #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 } |
输出:
1 2 3 | sqrt (2) = 1.414214 sin (0.5f) = 0.479426 sqrt (1 + 0.5i) = 1.029086+0.242934i |
参考
C11标准(ISO / IEC 9899:2011): 7.25类型通用数学<tgmath.h>(p:373-375) C99标准(ISO / IEC 9899:1999): 7.22类型通用数学<tgmath.h>(p:335-337)
C 语言中文开发手册
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架