Skip to content

C 标准库 - <math.h>

概述

<math.h> 头文件提供了各种数学函数,包括三角函数、指数函数、对数函数、幂函数、舍入函数等。这些函数主要用于科学计算、工程计算和图形处理等领域。

数学函数类型

1. 三角函数

sin()

c
double sin(double x);
float sinf(float x);
long double sinl(long double x);

计算正弦值(弧度)。

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

int main() {
    double angle = M_PI / 4;
    double result = sin(angle);
    printf("sin(π/4) = %f\n", result);
    return 0;
}

cos()

c
double cos(double x);
float cosf(float x);
long double cosl(long double x);

计算余弦值(弧度)。

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

int main() {
    double angle = M_PI / 3;
    double result = cos(angle);
    printf("cos(π/3) = %f\n", result);
    return 0;
}

tan()

c
double tan(double x);
float tanf(float x);
long double tanl(long double x);

计算正切值(弧度)。

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

int main() {
    double angle = M_PI / 4;
    double result = tan(angle);
    printf("tan(π/4) = %f\n", result);
    return 0;
}

asin()

c
double asin(double x);
float asinf(float x);
long double asinl(long double x);

计算反正弦值(返回弧度)。

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

int main() {
    double value = 0.5;
    double result = asin(value);
    printf("asin(0.5) = %f 弧度\n", result);
    printf("asin(0.5) = %f\n", result * 180 / M_PI);
    return 0;
}

acos()

c
double acos(double x);
float acosf(float x);
long double acosl(long double x);

计算反余弦值(返回弧度)。

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

int main() {
    double value = 0.5;
    double result = acos(value);
    printf("acos(0.5) = %f 弧度\n", result);
    printf("acos(0.5) = %f\n", result * 180 / M_PI);
    return 0;
}

atan()

c
double atan(double x);
float atanf(float x);
long double atanl(long double x);

计算反正切值(返回弧度)。

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

int main() {
    double value = 1.0;
    double result = atan(value);
    printf("atan(1.0) = %f 弧度\n", result);
    printf("atan(1.0) = %f\n", result * 180 / M_PI);
    return 0;
}

atan2()

c
double atan2(double y, double x);
float atan2f(float y, float x);
long double atan2l(long double y, long double x);

计算 y/x 的反正切值(返回弧度),考虑象限。

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

int main() {
    double y = 1.0;
    double x = 1.0;
    double result = atan2(y, x);
    printf("atan2(1.0, 1.0) = %f 弧度\n", result);
    printf("atan2(1.0, 1.0) = %f\n", result * 180 / M_PI);
    return 0;
}

2. 双曲函数

sinh()

c
double sinh(double x);
float sinhf(float x);
long double sinhl(long double x);

计算双曲正弦值。

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

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

cosh()

c
double cosh(double x);
float coshf(float x);
long double coshl(long double x);

计算双曲余弦值。

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

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

tanh()

c
double tanh(double x);
float tanhf(float x);
long double tanhl(long double x);

计算双曲正切值。

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

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

3. 指数和对数函数

exp()

c
double exp(double x);
float expf(float x);
long double expl(long double x);

计算 e 的 x 次方。

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

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

log()

c
double log(double x);
float logf(float x);
long double logl(long double x);

计算自然对数(以 e 为底)。

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

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

log10()

c
double log10(double x);
float log10f(float x);
long double log10l(long double x);

计算常用对数(以 10 为底)。

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

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

log2()

c
double log2(double x);
float log2f(float x);
long double log2l(long double x);

计算以 2 为底的对数(C99)。

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

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

4. 幂函数

pow()

c
double pow(double x, double y);
float powf(float x, float y);
long double powl(long double x, long double y);

计算 x 的 y 次方。

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

int main() {
    double x = 2.0;
    double y = 10.0;
    double result = pow(x, y);
    printf("pow(2.0, 10.0) = %f\n", result);
    return 0;
}

sqrt()

c
double sqrt(double x);
float sqrtf(float x);
long double sqrtl(long double x);

计算平方根。

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

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

cbrt()

c
double cbrt(double x);
float cbrtf(float x);
long double cbrtl(long double x);

计算立方根(C99)。

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

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

hypot()

c
double hypot(double x, double y);
float hypotf(float x, float y);
long double hypotl(long double x, long double y);

计算直角三角形的斜边长度。

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

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

5. 舍入函数

ceil()

c
double ceil(double x);
float ceilf(float x);
long double ceill(long double x);

向上取整。

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

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

floor()

c
double floor(double x);
float floorf(float x);
long double floorl(long double x);

向下取整。

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

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

round()

c
double round(double x);
float roundf(float x);
long double roundl(long double x);

四舍五入到最近的整数(C99)。

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

int main() {
    double x1 = 3.14;
    double x2 = 3.5;
    printf("round(3.14) = %f\n", round(x1));
    printf("round(3.5) = %f\n", round(x2));
    return 0;
}

trunc()

c
double trunc(double x);
float truncf(float x);
long double truncl(long double x);

截断小数部分(C99)。

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

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

6. 绝对值函数

fabs()

c
double fabs(double x);
float fabsf(float x);
long double fabsl(long double x);

计算浮点数的绝对值。

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

int main() {
    double x = -5.5;
    double result = fabs(x);
    printf("fabs(-5.5) = %f\n", result);
    return 0;
}

7. 取余函数

fmod()

c
double fmod(double x, double y);
float fmodf(float x, float y);
long double fmodl(long double x, long double y);

计算浮点数除法的余数。

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

int main() {
    double x = 10.5;
    double y = 3.0;
    double result = fmod(x, y);
    printf("fmod(10.5, 3.0) = %f\n", result);
    return 0;
}

remainder()

c
double remainder(double x, double y);
float remainderf(float x, float y);
long double remainderl(long double x, long double y);

计算 IEEE 754 余数(C99)。

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

int main() {
    double x = 10.5;
    double y = 3.0;
    double result = remainder(x, y);
    printf("remainder(10.5, 3.0) = %f\n", result);
    return 0;
}

8. 其他数学函数

fma()

c
double fma(double x, double y, double z);
float fmaf(float x, float y, float z);
long double fmal(long double x, long double y, long double z);

融合乘加运算(C99)。

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

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

fmax()

c
double fmax(double x, double y);
float fmaxf(float x, float y);
long double fmaxl(long double x, long double y);

返回两个数中的最大值(C99)。

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

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

fmin()

c
double fmin(double x, double y);
float fminf(float x, float y);
long double fminl(long double x, long double y);

返回两个数中的最小值(C99)。

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

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

数学常量

c
#define M_E         2.71828182845904523536
#define M_LOG2E     1.4426950408889634074
#define M_LOG10E    0.43429448190325182765
#define M_LN2       0.69314718055994530942
#define M_LN10      2.30258509299404568402
#define M_PI        3.14159265358979323846
#define M_PI_2      1.57079632679489661923
#define M_PI_4      0.78539816339744830962
#define M_1_PI      0.31830988618379067154
#define M_2_PI      0.63661977236758134308
#define M_2_SQRTPI  1.12837916709551257390
#define M_SQRT2     1.41421356237309504880
#define M_SQRT1_2   0.70710678118654752440

实际应用示例

1. 计算三角形面积

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

double triangle_area(double a, double b, double c) {
    double s = (a + b + c) / 2.0;
    return sqrt(s * (s - a) * (s - b) * (s - c));
}

int main() {
    double a = 3.0, b = 4.0, c = 5.0;
    double area = triangle_area(a, b, c);
    printf("三角形面积: %.2f\n", area);
    return 0;
}

2. 计算两点之间的距离

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

typedef struct {
    double x;
    double y;
} Point;

double distance(Point p1, Point p2) {
    return hypot(p2.x - p1.x, p2.y - p1.y);
}

int main() {
    Point p1 = {0.0, 0.0};
    Point p2 = {3.0, 4.0};
    double dist = distance(p1, p2);
    printf("两点之间的距离: %.2f\n", dist);
    return 0;
}

3. 角度转换

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

double degrees_to_radians(double degrees) {
    return degrees * M_PI / 180.0;
}

double radians_to_degrees(double radians) {
    return radians * 180.0 / M_PI;
}

int main() {
    double degrees = 90.0;
    double radians = degrees_to_radians(degrees);
    printf("%.2f 度 = %.2f 弧度\n", degrees, radians);
    
    radians = M_PI / 2;
    degrees = radians_to_degrees(radians);
    printf("%.2f 弧度 = %.2f\n", radians, degrees);
    
    return 0;
}

4. 计算圆的面积和周长

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

double circle_area(double radius) {
    return M_PI * radius * radius;
}

double circle_circumference(double radius) {
    return 2 * M_PI * radius;
}

int main() {
    double radius = 5.0;
    printf("圆的面积: %.2f\n", circle_area(radius));
    printf("圆的周长: %.2f\n", circle_circumference(radius));
    return 0;
}

5. 计算球体的表面积和体积

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

double sphere_surface_area(double radius) {
    return 4 * M_PI * radius * radius;
}

double sphere_volume(double radius) {
    return (4.0 / 3.0) * M_PI * pow(radius, 3);
}

int main() {
    double radius = 5.0;
    printf("球体的表面积: %.2f\n", sphere_surface_area(radius));
    printf("球体的体积: %.2f\n", sphere_volume(radius));
    return 0;
}

6. 复利计算

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

double compound_interest(double principal, double rate, int years) {
    return principal * pow(1 + rate / 100.0, years);
}

int main() {
    double principal = 10000.0;
    double rate = 5.0;
    int years = 10;
    
    double amount = compound_interest(principal, rate, years);
    printf("本金: %.2f, 利率: %.2f%%, 年限: %d\n", principal, rate, years);
    printf("复利金额: %.2f\n", amount);
    
    return 0;
}

7. 计算标准差

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

double calculate_mean(double data[], int size) {
    double sum = 0.0;
    for (int i = 0; i < size; i++) {
        sum += data[i];
    }
    return sum / size;
}

double calculate_stddev(double data[], int size) {
    double mean = calculate_mean(data, size);
    double sum = 0.0;
    
    for (int i = 0; i < size; i++) {
        sum += pow(data[i] - mean, 2);
    }
    
    return sqrt(sum / size);
}

int main() {
    double data[] = {1.0, 2.0, 3.0, 4.0, 5.0};
    int size = sizeof(data) / sizeof(data[0]);
    
    double mean = calculate_mean(data, size);
    double stddev = calculate_stddev(data, size);
    
    printf("平均值: %.2f\n", mean);
    printf("标准差: %.2f\n", stddev);
    
    return 0;
}

错误处理

数学函数可能会设置 errno 来指示错误:

  • EDOM - 域错误(参数超出函数定义域)
  • ERANGE - 范围错误(结果超出可表示范围)
c
#include <stdio.h>
#include <math.h>
#include <errno.h>

int main() {
    errno = 0;
    double result = sqrt(-1.0);
    
    if (errno == EDOM) {
        printf("域错误: 参数必须是非负数\n");
    }
    
    errno = 0;
    result = exp(1000.0);
    
    if (errno == ERANGE) {
        printf("范围错误: 结果超出可表示范围\n");
    }
    
    return 0;
}

总结

<math.h> 提供的数学函数是 C 语言中进行科学计算的基础工具。这些函数具有以下特点:

  1. 功能全面 - 涵盖了三角函数、指数函数、对数函数、幂函数等
  2. 精度高 - 使用浮点数运算,提供高精度计算
  3. 类型多样 - 支持 float、double 和 long double 类型
  4. 标准兼容 - 遵循 IEEE 754 浮点数标准

记住:

  • 三角函数使用弧度而不是角度
  • 注意函数的定义域和值域
  • 检查 errno 来处理错误
  • 使用适当的函数类型(float、double、long double)