数学函数

数学相关函数

算法数据范围初定:单数据 10 的 9 次方以内无脑用 int,单数据 10 的 18 次方以内无脑 long long,更高的数据量需要考虑 long double(10 的 308 次方左右),但是注意:long double 虽然能表示很大的数,但精度不够稳定,误差较大!对准确性要求极高的场景下,就不太靠谱了。这时就需要考虑高精度算法和计算库了。还有在多数据涉及加法和乘法操作时,注意边界溢出!

1. 基本数学函数(<cmath>

功能 函数原型 使用示例 注意事项
平方根 double sqrt(double x) sqrt(16.0) = 4.0 参数需非负
幂运算 (b e ) double pow(double b, double e) pow(2.0, 3.0) = 8.0 效率低于位运算
浮点数绝对值 double abs(double x) abs(-3.14) = 3.14 整数用 <cstdlib>abs()
浮点数绝对值 double fabs(double x) fabs(-2.5) = 2.5 abs()
向上取整 double ceil(double x) ceil(2.3) = 3.0
向下取整 double floor(double x) floor(2.7) = 2.0
四舍五入 double round(double x) round(2.5) = 3.0 C++11
浮点数取模 double fmod(double a, double b) fmod(5.5, 2.0) = 1.5 余数 = a - b*trunc(a/b)
欧几里得距离 (√(x²+y²)) double hypot(double x, double y) hypot(3,4) = 5.0 避免溢出
自然对数 (ln x) double log(double x) log(exp(1)) ≈ 1.0 x > 0
常用对数 (log₁₀ x) double log10(double x) log10(100) = 2.0 x > 0

2. 数值算法(<algorithm> & <numeric>

功能 函数原型 使用示例 注意事项
最大值 T max(T a, T b) max(3, 5) = 5 支持多参数 max({a,b,c})
最小值 T min(T a, T b) min(2.0, 1.5) = 1.5 支持多参数
绝对值 T abs(T x) abs(-10) = 10 模板版本
最大公约数 int gcd(int a, int b) (C++17) gcd(12, 18) = 6 C++17 需 <numeric>
最小公倍数 int lcm(int a, int b) (C++17) lcm(4, 6) = 12 C++17 需 <numeric>
区间求和 T accumulate(It first, It last, T init) accumulate(v.begin(), v.end(), 0) <numeric>
填充递增序列 void iota(It first, It last, T value) iota(v.begin(), v.end(), 1) <numeric>,生成 1,2,3,…

3. 常见相关常量(也在 <climits> 中):

功能
int 最大值(通常是 2³¹−1) INT_MAX
int 最小值(通常是 -2³¹) INT_MIN
long long 最大值 LLONG_MAX
long long 最小值 LLONG_MIN
大概是 INT_MAX 的一半,本质是一个 16 进制数,常用于防溢出 0x3f3f3f3f(f 可大写可小写)
unsigned int 最大值 UINT_MAX
char 最大值 CHAR_MAX
long 最大值 LONG_MAX
short 最大值 SHRT_MAX

注意事项:

  • 不要混淆 <climits>(C++) 和 <limits.h>(C)。
  • 如果你用的是 C++,推荐使用 <climits>
  • INT_MAX 是编译器根据系统架构定义的,保证可移植性。

4. 位运算函数(GCC 内置)

功能 函数原型 使用示例 返回值
二进制中 1 的个数 int __builtin_popcount(unsigned int x) __builtin_popcount(7) = 3 32 位整数
前导 0 的个数 int __builtin_clz(unsigned int x) __builtin_clz(1) = 31 32 位整数(MSB 开始)
后缀 0 的个数 int __builtin_ctz(unsigned int x) __builtin_ctz(8) = 3 32 位整数(LSB 开始)
最低位 1 的位置 int __builtin_ffs(int x) __builtin_ffs(6) = 2 位置从 1 开始计数

5. 随机数(<cstdlib>

功能 函数原型 使用示例 注意事项
生成伪随机数 int rand() rand() % 100 范围 [0, RAND_MAX]
设置随机种子 void srand(unsigned seed) srand(time(0)) <ctime>

使用技巧:

  1. 定义 π 常量

    1
    const double PI = acos(-1.0);  // 最精确的定义方式
  2. 整数绝对值

    1
    2
    #include <cstdlib>
    int a = abs(-10); // 整数用cstdlib的abs
  3. C++17 GCD/LCM

    1
    2
    #include <numeric>
    cout << gcd(12, 18) << " " << lcm(4, 6); // 输出: 6 12
  4. 位运算优化

    1
    2
    3
    4
    5
    // 判断2的幂次
    bool isPowerOfTwo(int n)
    {
    return n > 0 && (n & (n - 1)) == 0;
    }
  5. 随机数生成

    1
    2
    3
    4
    #include <cstdlib>
    #include <ctime>
    srand(time(0)); // 初始化随机种子
    int randNum = rand() % 100; // 0-99的随机数

注意:竞赛中常用 GCC 编译器,可使用 __builtin 系列函数优化位运算操作。C++17 及以上建议使用标准库的 gcd()lcm() 函数。

6. 三角函数(<cmath>

功能 函数原型 使用示例 注意事项
正弦 double sin(double rad) sin(M_PI/2) = 1.0 参数为弧度(非角度)
余弦 double cos(double rad) cos(M_PI) = -1.0 需定义 #define M_PI 3.1415926535
正切 double tan(double rad) tan(M_PI/4) ≈ 1.0
反正弦 double asin(double x) asin(1.0) = M_PI/2 返回值 ∈ [-π/2, π/2]
反余弦 double acos(double x) acos(-1.0) = M_PI 返回值 ∈ [0, π]
反正切 double atan(double x) atan(1.0) = M_PI/4 返回值 ∈ [-π/2, π/2]