Appearance
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> 提供的类型泛型宏简化了不同精度浮点数和复数的使用:
- 简化代码 - 自动选择合适的函数变体
- 类型安全 - 根据参数类型自动匹配
- 易于维护 - 减少代码重复
- 广泛应用 - 适用于需要多种精度的科学计算
记住:
- 类型泛型宏根据参数类型自动选择函数
- 支持浮点数和复数
- 注意参数类型和返回类型的匹配
- 理解不同精度的影响
- 在需要高精度时使用 long double