Skip to content

C 标准库 - <tgmath.h>

概述

<tgmath.h> 头文件提供了类型泛型数学宏,根据参数类型自动选择合适的数学函数。这是 C99 标准引入的头文件,简化了不同精度浮点数和复数的使用。

类型泛型宏

三角函数

sin()

c
#define sin(x) /* 类型泛型正弦函数 */

根据参数类型自动选择 sin()、sinf()、sinl()、csin()、csinf() 或 csinl()。

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

int main() {
    float x_f = 1.0f;
    double x_d = 1.0;
    long double x_ld = 1.0L;
    
    float complex z_f = 1.0f + 1.0f * I;
    double complex z_d = 1.0 + 1.0 * I;
    
    printf("sin(1.0f) = %.6f\n", sin(x_f));
    printf("sin(1.0) = %.6f\n", sin(x_d));
    printf("sin(1.0L) = %.6Lf\n", sin(x_ld));
    printf("sin(1.0 + 1.0i) = %.6f + %.6fi\n", 
           creal(sin(z_d)), cimag(sin(z_d)));
    
    return 0;
}

cos()

c
#define cos(x) /* 类型泛型余弦函数 */

根据参数类型自动选择 cos()、cosf()、cosl()、ccos()、ccosf() 或 ccosl()。

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

int main() {
    float x_f = 1.0f;
    double x_d = 1.0;
    
    printf("cos(1.0f) = %.6f\n", cos(x_f));
    printf("cos(1.0) = %.6f\n", cos(x_d));
    
    return 0;
}

tan()

c
#define tan(x) /* 类型泛型正切函数 */

根据参数类型自动选择 tan()、tanf()、tanl()、ctan()、ctanf() 或 ctanl()。

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

int main() {
    double x = 1.0;
    
    printf("tan(1.0) = %.6f\n", tan(x));
    
    return 0;
}

asin()

c
#define asin(x) /* 类型泛型反正弦函数 */

根据参数类型自动选择 asin()、asinf()、asinl()、casin()、casinf() 或 casinl()。

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

int main() {
    double x = 0.5;
    
    printf("asin(0.5) = %.6f\n", asin(x));
    
    return 0;
}

acos()

c
#define acos(x) /* 类型泛型反余弦函数 */

根据参数类型自动选择 acos()、acosf()、acosl()、cacos()、cacosf() 或 cacosl()。

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

int main() {
    double x = 0.5;
    
    printf("acos(0.5) = %.6f\n", acos(x));
    
    return 0;
}

atan()

c
#define atan(x) /* 类型泛型反正切函数 */

根据参数类型自动选择 atan()、atanf()、atanl()、catan()、catanf() 或 catanl()。

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

int main() {
    double x = 1.0;
    
    printf("atan(1.0) = %.6f\n", atan(x));
    
    return 0;
}

atan2()

c
#define atan2(y, x) /* 类型泛型反正切函数 */

根据参数类型自动选择 atan2()、atan2f()、atan2l()。

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

int main() {
    double y = 1.0;
    double x = 1.0;
    
    printf("atan2(1.0, 1.0) = %.6f\n", atan2(y, x));
    
    return 0;
}

双曲函数

sinh()

c
#define sinh(x) /* 类型泛型双曲正弦函数 */

根据参数类型自动选择 sinh()、sinhf()、sinhl()、csinh()、csinhf() 或 csinhl()。

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

int main() {
    double x = 1.0;
    
    printf("sinh(1.0) = %.6f\n", sinh(x));
    
    return 0;
}

cosh()

c
#define cosh(x) /* 类型泛型双曲余弦函数 */

根据参数类型自动选择 cosh()、coshf()、coshl()、ccosh()、ccoshf() 或 ccoshl()。

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

int main() {
    double x = 1.0;
    
    printf("cosh(1.0) = %.6f\n", cosh(x));
    
    return 0;
}

tanh()

c
#define tanh(x) /* 类型泛型双曲正切函数 */

根据参数类型自动选择 tanh()、tanhf()、tanhl()、ctanh()、ctanhf() 或 ctanhl()。

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

int main() {
    double x = 1.0;
    
    printf("tanh(1.0) = %.6f\n", tanh(x));
    
    return 0;
}

asinh()

c
#define asinh(x) /* 类型泛型反双曲正弦函数 */

根据参数类型自动选择 asinh()、asinhf()、asinhl()、casinh()、casinhf() 或 casinhl()。

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

int main() {
    double x = 1.0;
    
    printf("asinh(1.0) = %.6f\n", asinh(x));
    
    return 0;
}

acosh()

c
#define acosh(x) /* 类型泛型反双曲余弦函数 */

根据参数类型自动选择 acosh()、acoshf()、acoshl()、cacosh()、cacoshf() 或 cacoshl()。

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

int main() {
    double x = 2.0;
    
    printf("acosh(2.0) = %.6f\n", acosh(x));
    
    return 0;
}

atanh()

c
#define atanh(x) /* 类型泛型反双曲正切函数 */

根据参数类型自动选择 atanh()、atanhf()、atanhl()、catanh()、catanhf() 或 catanhl()。

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

int main() {
    double x = 0.5;
    
    printf("atanh(0.5) = %.6f\n", atanh(x));
    
    return 0;
}

指数和对数函数

exp()

c
#define exp(x) /* 类型泛型指数函数 */

根据参数类型自动选择 exp()、expf()、expl()、cexp()、cexpf() 或 cexpl()。

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

int main() {
    float x_f = 1.0f;
    double x_d = 1.0;
    long double x_ld = 1.0L;
    
    printf("exp(1.0f) = %.6f\n", exp(x_f));
    printf("exp(1.0) = %.6f\n", exp(x_d));
    printf("exp(1.0L) = %.6Lf\n", exp(x_ld));
    
    return 0;
}

log()

c
#define log(x) /* 类型泛型自然对数函数 */

根据参数类型自动选择 log()、logf()、logl()、clog()、clogf() 或 clogl()。

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

int main() {
    double x = 2.0;
    
    printf("log(2.0) = %.6f\n", log(x));
    
    return 0;
}

log10()

c
#define log10(x) /* 类型泛型常用对数函数 */

根据参数类型自动选择 log10()、log10f()、log10l()。

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

int main() {
    double x = 100.0;
    
    printf("log10(100.0) = %.6f\n", log10(x));
    
    return 0;
}

log2()

c
#define log2(x) /* 类型泛型以2为底的对数函数 */

根据参数类型自动选择 log2()、log2f()、log2l()。

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

int main() {
    double x = 8.0;
    
    printf("log2(8.0) = %.6f\n", log2(x));
    
    return 0;
}

log1p()

c
#define log1p(x) /* 类型泛型 log(1+x) 函数 */

根据参数类型自动选择 log1p()、log1pf()、log1pl()。

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

int main() {
    double x = 0.001;
    
    printf("log1p(0.001) = %.6f\n", log1p(x));
    
    return 0;
}

幂函数

pow()

c
#define pow(x, y) /* 类型泛型幂函数 */

根据参数类型自动选择 pow()、powf()、powl()、cpow()、cpowf() 或 cpowl()。

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

int main() {
    float x_f = 2.0f;
    double x_d = 2.0;
    long double x_ld = 2.0L;
    
    printf("pow(2.0f, 3.0f) = %.6f\n", pow(x_f, 3.0f));
    printf("pow(2.0, 3.0) = %.6f\n", pow(x_d, 3.0));
    printf("pow(2.0L, 3.0L) = %.6Lf\n", pow(x_ld, 3.0L));
    
    return 0;
}

sqrt()

c
#define sqrt(x) /* 类型泛型平方根函数 */

根据参数类型自动选择 sqrt()、sqrtf()、sqrtl()、csqrt()、csqrtf() 或 csqrtl()。

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

int main() {
    float x_f = 4.0f;
    double x_d = 4.0;
    long double x_ld = 4.0L;
    
    printf("sqrt(4.0f) = %.6f\n", sqrt(x_f));
    printf("sqrt(4.0) = %.6f\n", sqrt(x_d));
    printf("sqrt(4.0L) = %.6Lf\n", sqrt(x_ld));
    
    return 0;
}

cbrt()

c
#define cbrt(x) /* 类型泛型立方根函数 */

根据参数类型自动选择 cbrt()、cbrtf()、cbrtl()。

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

int main() {
    double x = 8.0;
    
    printf("cbrt(8.0) = %.6f\n", cbrt(x));
    
    return 0;
}

hypot()

c
#define hypot(x, y) /* 类型泛型斜边函数 */

根据参数类型自动选择 hypot()、hypotf()、hypotl()。

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

int main() {
    double x = 3.0;
    double y = 4.0;
    
    printf("hypot(3.0, 4.0) = %.6f\n", hypot(x, y));
    
    return 0;
}

误差函数

erf()

c
#define erf(x) /* 类型泛型误差函数 */

根据参数类型自动选择 erf()、erff()、erfl()。

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

int main() {
    double x = 1.0;
    
    printf("erf(1.0) = %.6f\n", erf(x));
    
    return 0;
}

erfc()

c
#define erfc(x) /* 类型泛型互补误差函数 */

根据参数类型自动选择 erfc()、erfcf()、erfcl()。

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

int main() {
    double x = 1.0;
    
    printf("erfc(1.0) = %.6f\n", erfc(x));
    
    return 0;
}

伽马函数

tgamma()

c
#define tgamma(x) /* 类型泛型伽马函数 */

根据参数类型自动选择 tgamma()、tgammaf()、tgammal()。

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

int main() {
    double x = 5.0;
    
    printf("tgamma(5.0) = %.6f\n", tgamma(x));
    
    return 0;
}

lgamma()

c
#define lgamma(x) /* 类型泛型对数伽马函数 */

根据参数类型自动选择 lgamma()、lgammaf()、lgammal()。

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

int main() {
    double x = 5.0;
    
    printf("lgamma(5.0) = %.6f\n", lgamma(x));
    
    return 0;
}

取整函数

ceil()

c
#define ceil(x) /* 类型泛型向上取整函数 */

根据参数类型自动选择 ceil()、ceilf()、ceill()。

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

int main() {
    double x = 3.7;
    
    printf("ceil(3.7) = %.0f\n", ceil(x));
    
    return 0;
}

floor()

c
#define floor(x) /* 类型泛型向下取整函数 */

根据参数类型自动选择 floor()、floorf()、floorl()。

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

int main() {
    double x = 3.7;
    
    printf("floor(3.7) = %.0f\n", floor(x));
    
    return 0;
}

trunc()

c
#define trunc(x) /* 类型泛型截断函数 */

根据参数类型自动选择 trunc()、truncf()、truncl()。

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

int main() {
    double x = 3.7;
    
    printf("trunc(3.7) = %.0f\n", trunc(x));
    
    return 0;
}

round()

c
#define round(x) /* 类型泛型四舍五入函数 */

根据参数类型自动选择 round()、roundf()、roundl()。

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

int main() {
    double x = 3.7;
    
    printf("round(3.7) = %.0f\n", round(x));
    
    return 0;
}

lround()

c
#define lround(x) /* 类型泛型四舍五入到long函数 */

根据参数类型自动选择 lround()、lroundf()、lroundl()。

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

int main() {
    double x = 3.7;
    
    printf("lround(3.7) = %ld\n", lround(x));
    
    return 0;
}

llround()

c
#define llround(x) /* 类型泛型四舍五入到long long函数 */

根据参数类型自动选择 llround()、llroundf()、llroundl()。

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

int main() {
    double x = 3.7;
    
    printf("llround(3.7) = %lld\n", llround(x));
    
    return 0;
}

绝对值函数

fabs()

c
#define fabs(x) /* 类型泛型绝对值函数 */

根据参数类型自动选择 fabs()、fabsf()、fabsl()、cabs()、cabsf() 或 cabsl()。

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

int main() {
    float x_f = -3.7f;
    double x_d = -3.7;
    long double x_ld = -3.7L;
    
    printf("fabs(-3.7f) = %.6f\n", fabs(x_f));
    printf("fabs(-3.7) = %.6f\n", fabs(x_d));
    printf("fabs(-3.7L) = %.6Lf\n", fabs(x_ld));
    
    return 0;
}

取余函数

fmod()

c
#define fmod(x, y) /* 类型泛型取余函数 */

根据参数类型自动选择 fmod()、fmodf()、fmodl()。

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

int main() {
    double x = 5.3;
    double y = 2.0;
    
    printf("fmod(5.3, 2.0) = %.6f\n", fmod(x, y));
    
    return 0;
}

remainder()

c
#define remainder(x, y) /* 类型泛型IEEE取余函数 */

根据参数类型自动选择 remainder()、remainderf()、remainderl()。

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

int main() {
    double x = 5.3;
    double y = 2.0;
    
    printf("remainder(5.3, 2.0) = %.6f\n", remainder(x, y));
    
    return 0;
}

其他函数

fma()

c
#define fma(x, y, z) /* 类型泛型融合乘加函数 */

根据参数类型自动选择 fma()、fmaf()、fmal()。

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

int main() {
    double x = 2.0;
    double y = 3.0;
    double z = 4.0;
    
    printf("fma(2.0, 3.0, 4.0) = %.6f\n", fma(x, y, z));
    
    return 0;
}

fmax()

c
#define fmax(x, y) /* 类型泛型最大值函数 */

根据参数类型自动选择 fmax()、fmaxf()、fmaxl()。

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

int main() {
    double x = 3.7;
    double y = 2.5;
    
    printf("fmax(3.7, 2.5) = %.6f\n", fmax(x, y));
    
    return 0;
}

fmin()

c
#define fmin(x, y) /* 类型泛型最小值函数 */

根据参数类型自动选择 fmin()、fminf()、fminl()。

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

int main() {
    double x = 3.7;
    double y = 2.5;
    
    printf("fmin(3.7, 2.5) = %.6f\n", fmin(x, y));
    
    return 0;
}

fdim()

c
#define fdim(x, y) /* 类型泛型正差值函数 */

根据参数类型自动选择 fdim()、fdimf()、fdiml()。

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

int main() {
    double x = 5.0;
    double y = 3.0;
    
    printf("fdim(5.0, 3.0) = %.6f\n", fdim(x, y));
    
    return 0;
}

copysign()

c
#define copysign(x, y) /* 类型泛型复制符号函数 */

根据参数类型自动选择 copysign()、copysignf()、copysignl()。

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

int main() {
    double x = 3.7;
    double y = -2.5;
    
    printf("copysign(3.7, -2.5) = %.6f\n", copysign(x, y));
    
    return 0;
}

nan()

c
#define nan(tag) /* 类型泛型NaN函数 */

根据参数类型自动选择 nan()、nanf()、nanl()。

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

int main() {
    double x = nan("");
    
    printf("nan() = %f\n", x);
    
    return 0;
}

实际应用示例

1. 多精度计算

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

void calculate_with_precision() {
    float x_f = 1.0f;
    double x_d = 1.0;
    long double x_ld = 1.0L;
    
    printf("float: sin(1.0f) = %.6f\n", sin(x_f));
    printf("double: sin(1.0) = %.6f\n", sin(x_d));
    printf("long double: sin(1.0L) = %.6Lf\n", sin(x_ld));
}

int main() {
    calculate_with_precision();
    
    return 0;
}

2. 复数运算

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

void complex_calculations() {
    double complex z = 1.0 + 1.0 * I;
    
    printf("复数: %.2f + %.2fi\n", creal(z), cimag(z));
    printf("sin(z) = %.2f + %.2fi\n", creal(sin(z)), cimag(sin(z)));
    printf("cos(z) = %.2f + %.2fi\n", creal(cos(z)), cimag(cos(z)));
    printf("exp(z) = %.2f + %.2fi\n", creal(exp(z)), cimag(exp(z)));
    printf("log(z) = %.2f + %.2fi\n", creal(log(z)), cimag(log(z)));
}

int main() {
    complex_calculations();
    
    return 0;
}

3. 三角函数表

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

void print_trig_table() {
    printf("角度\t正弦\t余弦\t正切\n");
    for (int i = 0; i <= 360; i += 30) {
        double radians = i * 3.14159265358979323846 / 180.0;
        printf("%d\t%.4f\t%.4f\t%.4f\n", 
               i, sin(radians), cos(radians), tan(radians));
    }
}

int main() {
    print_trig_table();
    
    return 0;
}

4. 指数增长

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

void exponential_growth() {
    double initial = 1000.0;
    double rate = 0.05;
    
    printf("年份\t金额\n");
    for (int year = 0; year <= 10; year++) {
        double amount = initial * exp(rate * year);
        printf("%d\t%.2f\n", year, amount);
    }
}

int main() {
    exponential_growth();
    
    return 0;
}

5. 统计计算

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

void statistical_calculations() {
    double data[] = {1.0, 2.0, 3.0, 4.0, 5.0};
    int n = sizeof(data) / sizeof(data[0]);
    
    double sum = 0.0;
    for (int i = 0; i < n; i++) {
        sum += data[i];
    }
    double mean = sum / n;
    
    double variance = 0.0;
    for (int i = 0; i < n; i++) {
        variance += pow(data[i] - mean, 2);
    }
    variance /= n;
    
    double std_dev = sqrt(variance);
    
    printf("均值: %.2f\n", mean);
    printf("方差: %.2f\n", variance);
    printf("标准差: %.2f\n", std_dev);
}

int main() {
    statistical_calculations();
    
    return 0;
}

6. 物理计算

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

void physics_calculations() {
    double mass = 10.0;
    double velocity = 5.0;
    
    double kinetic_energy = 0.5 * mass * pow(velocity, 2);
    double momentum = mass * velocity;
    
    printf("质量: %.2f kg\n", mass);
    printf("速度: %.2f m/s\n", velocity);
    printf("动能: %.2f J\n", kinetic_energy);
    printf("动量: %.2f kg·m/s\n", momentum);
}

int main() {
    physics_calculations();
    
    return 0;
}

7. 几何计算

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

void geometric_calculations() {
    double radius = 5.0;
    
    double circumference = 2 * 3.14159265358979323846 * radius;
    double area = 3.14159265358979323846 * pow(radius, 2);
    double volume = (4.0 / 3.0) * 3.14159265358979323846 * pow(radius, 3);
    
    printf("半径: %.2f\n", radius);
    printf("周长: %.2f\n", circumference);
    printf("面积: %.2f\n", area);
    printf("体积: %.2f\n", volume);
}

int main() {
    geometric_calculations();
    
    return 0;
}

8. 信号处理

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

void signal_processing() {
    double frequency = 1.0;
    double amplitude = 1.0;
    
    printf("时间\t信号\n");
    for (double t = 0.0; t <= 2.0; t += 0.1) {
        double signal = amplitude * sin(2 * 3.14159265358979323846 * frequency * t);
        printf("%.1f\t%.4f\n", t, signal);
    }
}

int main() {
    signal_processing();
    
    return 0;
}

9. 数值积分

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

double integrate(double (*f)(double), double a, double b, int n) {
    double h = (b - a) / n;
    double sum = 0.5 * (f(a) + f(b));
    
    for (int i = 1; i < n; i++) {
        double x = a + i * h;
        sum += f(x);
    }
    
    return sum * h;
}

double square(double x) {
    return x * x;
}

int main() {
    double result = integrate(square, 0.0, 1.0, 1000);
    printf("∫x²dx 从 0 到 1 = %.6f\n", result);
    printf("理论值 = %.6f\n", 1.0 / 3.0);
    
    return 0;
}

10. 混合精度计算

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

void mixed_precision() {
    float x_f = 1.0f;
    double x_d = 1.0;
    long double x_ld = 1.0L;
    
    printf("float:\n");
    printf("  sin(1.0f) = %.6f\n", sin(x_f));
    printf("  exp(1.0f) = %.6f\n", exp(x_f));
    printf("  log(1.0f) = %.6f\n", log(x_f));
    
    printf("\ndouble:\n");
    printf("  sin(1.0) = %.6f\n", sin(x_d));
    printf("  exp(1.0) = %.6f\n", exp(x_d));
    printf("  log(1.0) = %.6f\n", log(x_d));
    
    printf("\nlong double:\n");
    printf("  sin(1.0L) = %.6Lf\n", sin(x_ld));
    printf("  exp(1.0L) = %.6Lf\n", exp(x_ld));
    printf("  log(1.0L) = %.6Lf\n", log(x_ld));
}

int main() {
    mixed_precision();
    
    return 0;
}

注意事项

1. 类型匹配

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

int main() {
    float x_f = 1.0f;
    double x_d = 1.0;
    
    printf("sin(1.0f) = %.6f\n", sin(x_f));
    printf("sin(1.0) = %.6f\n", sin(x_d));
    
    return 0;
}

2. 复数参数

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

int main() {
    double complex z = 1.0 + 1.0 * I;
    
    printf("sin(1.0 + 1.0i) = %.2f + %.2fi\n", 
           creal(sin(z)), cimag(sin(z)));
    
    return 0;
}

3. 参数数量

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

int main() {
    double x = 2.0;
    double y = 3.0;
    
    printf("pow(2.0, 3.0) = %.6f\n", pow(x, y));
    printf("hypot(2.0, 3.0) = %.6f\n", hypot(x, y));
    
    return 0;
}

4. 返回类型

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

int main() {
    float x_f = 1.0f;
    double x_d = 1.0;
    
    float result_f = sin(x_f);
    double result_d = sin(x_d);
    
    printf("sin(1.0f) 返回 float: %.6f\n", result_f);
    printf("sin(1.0) 返回 double: %.6f\n", result_d);
    
    return 0;
}

总结

<tgmath.h> 提供的类型泛型宏简化了不同精度浮点数和复数的使用:

  1. 简化代码 - 自动选择合适的函数变体
  2. 类型安全 - 根据参数类型自动匹配
  3. 易于维护 - 减少代码重复
  4. 广泛应用 - 适用于需要多种精度的科学计算

记住:

  • 类型泛型宏根据参数类型自动选择函数
  • 支持浮点数和复数
  • 注意参数类型和返回类型的匹配
  • 理解不同精度的影响
  • 在需要高精度时使用 long double