Ch 8: 数学与随机数
- 掌握 cmath 常用函数
- 理解 random 库的差异
- 处理复数和数值限制
- 生成均匀和正态分布
8.1 Python math 模块
Section titled “8.1 Python math 模块”math 提供了基本的数学函数:
import math
# 常数math.pi # 3.141592653589793math.e # 2.718281828459045math.tau # 6.283185307179586math.inf # 正无穷math.nan # 非数字
# 基本运算math.sqrt(16) # 4.0math.pow(2, 10) # 1024.0math.abs(-5) # 5math.ceil(3.2) # 4math.floor(3.8) # 3math.round(3.5) # 4math.trunc(-3.5) # -3(向零取整)
# 三角函数math.sin(math.pi / 2) # 1.0math.cos(0) # 1.0math.tan(math.pi / 4) # 1.0math.asin(1) # 1.5707963267948966 (arcsin)math.degrees(math.pi) # 180.0math.radians(180) # 3.141592653589793
# 指数和对数math.log(math.e) # 1.0math.log10(100) # 2.0math.log2(1024) # 10.0math.exp(1) # 2.718281828459045
# 特殊函数math.factorial(5) # 120math.gcd(48, 18) # 6math.isclose(0.1 + 0.2, 0.3) # Truemath.isfinite(x) # 是否有限math.isinf(x) # 是否无穷math.isnan(x) # 是否 NaN8.2 C++ cmath
Section titled “8.2 C++ cmath”cmath 提供了对应的数学函数:
#include <cmath>#include <iostream>#include <limits>
int main() { // 常数(C++ 需要定义或手动使用) const double PI = 3.141592653589793; const double E = 2.718281828459045;
// C++20 引入了标准数学常量 // #include <numbers> // std::numbers::pi, std::numbers::e
// 基本运算 std::sqrt(16); // 4.0 std::pow(2, 10); // 1024.0 std::abs(-5); // 5 std::ceil(3.2); // 4 std::floor(3.8); // 3 std::round(3.5); // 4 std::trunc(-3.5); // -3
// 三角函数 std::sin(PI / 2); // 1.0 std::cos(0); // 1.0 std::tan(PI / 4); // 1.0 std::asin(1); // 1.5707963267948966 std::acos(1); // 0.0 std::atan(1); // 0.7853981633974483
// 指数和对数 std::log(std::exp(1)); // 1.0 std::log10(100); // 2.0 std::log2(1024); // 10.0 std::exp(1); // 2.718281828459045
// 特殊函数 std::fabs(-5.0); // 5.0(浮点绝对值) std::fmax(1.0, 2.0); // 2.0 std::fmin(1.0, 2.0); // 1.0 std::hypot(3.0, 4.0); // 5.0 (勾股定理)
return 0;}C++ 数学常量(C++20)
Section titled “C++ 数学常量(C++20)”#include <numbers>#include <iostream>
int main() { std::cout << std::numbers::pi << std::endl; // 3.14159... std::cout << std::numbers::e << std::endl; // 2.71828... std::cout << std::numbers::sqrt2 << std::endl; // 1.41421... std::cout << std::numbers::phi << std::endl; // 黄金比例
return 0;}8.3 Python random 模块
Section titled “8.3 Python random 模块”import random
# 基础random.random() # [0, 1) 均匀分布random.randint(1, 100) # [1, 100] 整数random.choice([1,2,3]) # 随机选择random.shuffle(lst) # 洗牌(原地)
# 序列操作random.sample([1,2,3,4,5], 3) # 无放回抽样random.choices([1,2,3], k=5) # 有放回抽样
# 分布random.gauss(0, 1) # 正态分布random.expovariate(1) # 指数分布random.uniform(0, 1) # 均匀分布
# 种子random.seed(42)random.seed(0)8.4 C++ random 库
Section titled “8.4 C++ random 库”C++ random 比 Python 更复杂,但更强大:
#include <random>#include <vector>#include <iostream>
int main() { // 随机数引擎 std::random_device rd; // 真随机(通常较慢) std::mt19937 gen(rd()); // Mersenne Twister std::mt19937 gen2(42); // 确定性种子
// 均匀分布 std::uniform_int_distribution<int> dist_int(1, 100); // [1, 100] std::uniform_real_distribution<double> dist_real(0.0, 1.0); // [0, 1)
int x = dist_int(gen); // 随机整数 double y = dist_real(gen); // 随机浮点数
// 正态分布 std::normal_distribution<double> dist_norm(0.0, 1.0); // 均值0,标准差1 double z = dist_norm(gen);
// 洗牌 std::vector<int> v = {1, 2, 3, 4, 5}; std::shuffle(v.begin(), v.end(), gen);
// 选择 std::vector<int> nums = {1, 2, 3, 4, 5}; std::sample(nums.begin(), nums.end(), std::back_inserter(result), 3, gen); // 无放回
return 0;}| 分布 | Python | C++ | 说明 |
|---|---|---|---|
| 均匀整数 | randint(a, b) | uniform_int_distribution | [a, b] |
| 均匀浮点 | random() | uniform_real_distribution | [a, b) |
| 正态 | gauss(mu, sigma) | normal_distribution | 均值mu,标准差sigma |
| 指数 | expovariate(lambda) | exponential_distribution | 指数分布 |
引擎和分布的关系
Section titled “引擎和分布的关系”// 引擎:生成随机比特std::random_device rd; // 真随机std::mt19937 gen(rd()); // 伪随机 Mersenne Twisterstd::minstd_rand engine; // 线性同余
// 分布:从引擎采样并转换std::uniform_int_distribution<int> dist(1, 6);
// 组合int dice = dist(gen); // gen 生成随机比特,dist 转换成 1-6
// 常用组合std::mt19937 rng(std::random_device{}());std::uniform_int_distribution<int> dist(1, 100);std::normal_distribution<double> norm(0.0, 1.0);8.5 复数
Section titled “8.5 复数”Python
Section titled “Python”import cmathimport math
# 复数z = 3 + 4jz.real # 3.0z.imag # 4.0abs(z) # 5.0 (模)cmath.phase(z) # 0.9272952180016122 (幅角)cmath.rect(5, 0.927) # (3+4j)
# 复数函数cmath.sqrt(-1) # 1jcmath.exp(1j*math.pi) # (-1+0j)cmath.log(1j) # 1.5707963267948966j#include <complex>#include <cmath>
int main() { // 复数 std::complex<double> z(3.0, 4.0);
z.real(); // 3.0 z.imag(); // 4.0 std::abs(z); // 5.0 std::arg(z); // 0.927... std::polar(5.0, 0.927); // 复数
// 复数运算 std::complex<double> z2 = z * z; std::complex<double> z3 = std::sqrt(z); std::complex<double> z4 = std::exp(z);
return 0;}8.6 数值限制
Section titled “8.6 数值限制”Python
Section titled “Python”import sys
# 浮点限制sys.float_info.max # 最大浮点数sys.float_info.min # 最小正浮点数sys.float_info.epsilon # 机器 epsilonsys.float_info.dig # 精度位数
# 整数(Python 整数无限制)sys.maxsize # 最大列表/字符串大小sys.maxunicode # 最大 Unicode 码点#include <limits>#include <iostream>
int main() { // 整数限制 std::numeric_limits<int>::max(); // INT_MAX std::numeric_limits<int>::min(); // INT_MIN std::numeric_limits<int>::lowest(); // 最小值(负数)
// 无符号整数 std::numeric_limits<unsigned int>::max(); // UINT_MAX
// 浮点限制 std::numeric_limits<double>::max(); // 最大值 std::numeric_limits<double>::min(); // 最小正数 std::numeric_limits<double>::epsilon(); // 机器 epsilon std::numeric_limits<double>::infinity(); // 无穷大
// 检查属性 std::numeric_limits<int>::is_signed; // true std::numeric_limits<int>::is_integer; // true
return 0;}8.7 常用速查
Section titled “8.7 常用速查”| Python | C++ | 说明 |
|---|---|---|
math.sqrt | std::sqrt | 平方根 |
math.pow | std::pow | 幂 |
math.abs | std::abs | 绝对值 |
math.ceil | std::ceil | 向上取整 |
math.floor | std::floor | 向下取整 |
math.round | std::round | 四舍五入 |
math.sin | std::sin | 正弦 |
math.cos | std::cos | 余弦 |
math.log | std::log | 自然对数 |
math.log10 | std::log10 | 常用对数 |
math.exp | std::exp | 指数 |
math.pi | std::numbers::pi | 圆周率 |
random.random | uniform_real_distribution | 随机浮点 |
random.randint | uniform_int_distribution | 随机整数 |
random.gauss | normal_distribution | 正态分布 |
cmath提供数学函数random在 C++ 是独立的random库- C++ 随机数需要引擎+分布
std::numeric_limits获取类型限制
下章预告:ch09 序列化与数据格式。