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

<tgmath.h>头文件(三)

对于将结果舍入到更窄类型的函数,其泛型宏名称通过省略函数名中的后缀得到。具有f或者d前缀的泛型宏如下所示:

泛型宏 <math.h>头文件中函数 泛型宏 <math.h>头文件中函数
double long double long double
fadd fadd faddl dadd daddl
fsub fsub fsubl dsub dsubl
fmul fmul fmull dmul dmull
fdiv fdiv fdivl ddiv ddivl
ffma ffma ffmal dfma dfmal
fsqrt fsqrt fsqrtl dsqrt dsqrtl

具有d32或者d64前缀的泛型宏如下所示:

泛型宏 <math.h>头文件中函数 泛型宏 <math.h>头文件中函数
_Decimal64 _Decimal128 _Decimal128
d32add d32addd64 d32addd128 d64add d64addd128
d32sub d32subd64 d32subd128 d64sub d64subd128
d32mul d32muld64 d32muld128 d64mul d64muld128
d32div d32divd64 d32divd128 d64div d64divd128
d32fma d32fmad64 d32fmad128 d64fma d64fmad128
d32sqrt d32sqrtd64 d32sqrtd128 d64sqrt d64sqrtd128

所有实参应为实数类型。如果泛型宏前缀是f或者d,使用十进制浮点类型实参将导致未定义行为;如果泛型宏前缀是d32或者d64,使用标准浮点类型实参将导致未定义行为。

使用泛型宏时调用函数按以下方式确定:

- 如果任一实参具有_Decimal128类型,或者泛型宏前缀是d64,调用函数的名称是泛型宏的名称加上d128后缀;

- 否则,如果泛型宏前缀是d32,调用函数的名称是泛型宏的名称加上d64后缀;

- 否则,如果任一实参具有long double类型,或者泛型宏前缀是d,调用函数的名称是泛型宏的名称加上l后缀;

- 否则,调用函数的名称是泛型宏的名称(无任何后缀)。


以泛型宏fadd、dadd、d32add、d64add为例:

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
/*泛型宏fadd、dadd、d32add、d64add范例*/

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

int main(void)
{
    #if __STDC_VERSION_TGMATH_H__ >= 202311L
        /*调用函数fadd。*/
        printf("fadd(2.0, 5.0) = %.2f\n", fadd(2.0, 5.0));

        /*调用函数faddl。*/
        printf("fadd(2.0L, 5.0L) = %.2f\n", fadd(2.0L, 5.0L));

        /*调用函数daddl。*/
        printf("dadd(2.0L, 5.0L) = %.2f\n", dadd(2.0L, 5.0L));

    #else
        puts("The implementation does not support type-generic macros fadd and dadd.");

    #endif

    #if __STDC_VERSION_TGMATH_H__ >= 202311L && defined(__STDC_IEC_60559_DFP__)
        /*调用函数d32addd64。*/
        printf("d32add(2.0dd, 5.0dd) = %.2Hf\n", d32add(2.0dd, 5.0dd));

        /*调用函数d32addd128。*/
        printf("d32add(2.0dl, 5.0dl) = %.2Hf\n", d32add(2.0dl, 5.0dl));

        /*调用函数d64addd128。*/
        printf("d64add(2.0dl, 5.0dl) = %.2Df\n", d64add(2.0dl, 5.0dl));

    #else
        puts("The implementation does not support type-generic macros d32add and d64add.");

    #endif
 
    return 0;
}


输出:

The implementation does not support type-generic macros fadd and dadd.

The implementation does not support type-generic macros d32add and d64add.

(注:编译时实现还未支持fadd、dadd、d32add、d64add泛型宏。)


对于<math.h>头文件中具有d64后缀、且不存在无后缀版本的函数(decodedecd64、encodedecd64、decodebind64、encodebind64函数除外。),其泛型宏名称通过省略函数名中的后缀得到。这些泛型宏如下所示:

泛型宏 <math.h>头文件中函数
_Decimal32 _Decimal64 _Decimal128
quantize quantized32 quantized64 quantized128
samequantum samequantumd32 samequantumd64 samequantumd128
quantum quantumd32 quantumd64 quantumd128
llquantexp llquantexpd32 llquantexpd64 llquantexpd128

对于这些泛型宏,如果实参是标准浮点类型或者复数类型,或者实参全部是整数类型,其行为是未定义的。


以泛型宏quantum为例:

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

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

int main(void)
{
    #if __STDC_VERSION_TGMATH_H__ >= 202311L && defined(__STDC_IEC_60559_DFP__)
        /*调用函数quantumd32。*/
        printf("The quantum of %.2Hf is %.2Hf\n", 1.00df, quantum(1.00df));

        /*调用函数quantumd64。*/
        printf("The quantum of %.2Df is %.2Df\n", 1.00dd, quantum(1.00dd));

        /*调用函数quantumd128。*/
        printf("The quantum of %.2DDf is %.2DDf\n", 1.00dl, quantum(1.00dl));

    #else
        puts("The implementation does not support type-generic macro quantum.");

    #endif
 
    return 0;
}


输出:

The implementation does not support type-generic macro quantum.

(注:编译时实现还未支持quantum泛型宏。)



主要参考资料:

1、ISO/IEC 9899:2024

2、ISO/IEC 9899:2018