当前位置: C语言 -- 标准库 -- <tgmath.h>

<tgmath.h>头文件

<tgmath.h>头文件包括<math.h>头文件和<complex.h>头文件,并定义了一些泛型宏。

<math.h>头文件、<complex.h>头文件中没有f(float)或者l(long double)后缀的函数中,一些函数有一个或者多个double类型的形式参数;这些函数(modf函数除外。)都存在一个对应的泛型宏(type-generic macro)。与标准库中其它函数式宏一样,可以通过禁用泛型宏从而使相应的普通函数可用。函数概要(function synopsis)中对应实数类型为double类型的形式参数为泛型参数(generic parameters)。使用宏调用函数,函数对应的实数类型和类型域(type domain)由泛型参数对应的实际参数决定。如果实际参数的类型与所选函数的形式参数类型不兼容,其行为是未定义的。


使用宏调用函数,泛型参数的类型按以下规则确定:

-首先,如果泛型参数对应的实际参数中有参数是long double类型,泛型参数类型将为long double类型;

-否则,如果泛型参数对应的实际参数中有参数是double类型或者整数类型,泛型参数类型将为double类型;

-否则,泛型参数类型将为float类型。


以泛型宏fabs为例:

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
/*宏fabs范例*/

#include <stdio.h>
#include <tgmath.h>

/*判断数据类型的宏。*/
#define TYPE(x) _Generic((x),  \
                         float:"float type",  \
                         double:"double type",  \
                         long double:"long double type",  \
                         default:"unknown type"  \
                         )

int main(void)
{
    printf("TYPE(fabs(1)): %s\n", TYPE(fabs(1)));
    printf("TYPE(fabs(1.0)): %s\n", TYPE(fabs(1.0)));
    printf("TYPE(fabs(1.0f)): %s\n", TYPE(fabs(1.0f)));
    printf("TYPE(fabs(1.0L)): %s\n", TYPE(fabs(1.0L)));
    
    return 0;
}


输出:

TYPE(fabs(1)): double type

TYPE(fabs(1.0)): double type

TYPE(fabs(1.0f)): float type

TYPE(fabs(1.0L)): long double type


对于<math.h>头文件中没有后缀的函数以及<complex.h>头文件中的同名函数(存在字母前缀c。),对应的泛型宏是相同的。泛型宏fabs是个例外,其对应的函数分别是fabs(<math.h>头文件)和cabs(<complex.h>头文件)。

上述函数与泛型宏的对应关系如下表所示:

泛型宏 <math.h>头文件中函数 <complex.h>头文件中函数
float double long double float double long double
acos acosf acos acosl cacosf cacos cacosl
asin asinf asin asinl casinf casin casinl
atan atanf atan atanl catanf catan catanl
acosh acoshf acosh acoshl cacoshf cacosh cacoshl
asinh asinhf asinh asinhl casinhf casinh casinhl
atanh atanhf atanh atanhl catanhf catanh catanhl
cos cosf cos cosl ccosf ccos ccosl
sin sinf sin sinl csinf csin csinl
tan tanf tan tanl ctanf ctan ctanl
cosh coshf cosh coshl ccoshf ccosh ccoshl
sinh sinhf sinh sinhl csinhf csinh csinhl
tanh tanhf tanh tanhl ctanhf ctanh ctanhl
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
fabs fabsf fabs fabsl cabsf cabs cabsl

如果泛型宏中至少一个实际参数是复数,将调用复数函数;如果泛型宏中没有实际参数是复数,将调用实数函数。


以泛型宏sin为例:

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
/*宏sin范例*/

#include <stdio.h>
#include <tgmath.h>

int main(void)
{
    double numberReal;
    double complex numberComplex;

    /*调用<math.h>头文件中的sin函数。*/
    numberReal = sin(1.0);
    printf("sin(1.0) = %.2f\n", numberReal);

    /*调用<complex.h>头文件中的csin函数。*/
    numberComplex = sin(1.0+1.0i);
    printf("sin(1.0+1.0i) = %.2f%+.2fi\n",creal(numberComplex), cimag(numberComplex));
 
    return 0;
}


输出:

sin(1.0) = 0.84

sin(1.0+1.0i) = 1.30+0.63i