对数 = 指数的「倒着问」——2 的几次方等于 8?exp = 复利增长的「速度表」,e 是大自然的极限增速。
乘方是「给次数,算结果」:2³ = 8。对数是「给结果,问次数」:2 的几次方等于 8?答案是 3,写作 log₂8 = 3。想象折纸:一张 8 层的纸,对折几次变成 1 层?折 3 次——「对折几次到 1」就是 log₂。计算机里 log₂ 无处不在:n 个状态要用几个 bit 区分?二分查找能把范围砍多少刀?都是它。C++ 里:log2(x) 以 2 为底、log10(x) 以 10 为底、log(x) 以 e 为底(自然对数);exp(x) = eˣ,是复利、病毒式传播背后的「增长引擎」。
// 手推:折纸 + bit 对照表 层数 8 → 4 → 2 → 1 折 3 次 log₂8 = 3 层数 16 → 8 → 4 → 2 → 1 折 4 次 log₂16 = 4 规律:log₂(2ⁿ) = n(2 的 n 次方,对折 n 次) 区分 n 个状态需要几个 bit? 2 个状态(0/1) → 1 个 bit(2¹ = 2) 4 个状态(0~3) → 2 个 bit(2² = 4) 8 个状态(0~7) → 3 个 bit(2³ = 8) 16 个状态(0~15) → 4 个 bit(2⁴ = 16) 1024 个状态 → 10 个 bit(2¹⁰ = 1024) // C++ 验证 #include <cmath> cout << log2(8); // 3 cout << log2(1024); // 10 cout << log2(10); // ≈ 3.322(10 不是 2 的幂)
log(x) 是自然对数(底 e),不是以 10 为底。// 手推:log10 与位数 10 = 10¹ → log10 = 1 → 位数 = 1 + 1 = 2 100 = 10² → log10 = 2 → 位数 = 2 + 1 = 3 1000 = 10³ → log10 = 3 → 位数 = 3 + 1 = 4 582385 → log10 ≈ 5.765 → 位数 = 5 + 1 = 6 ✓ // C++ 里三个「log」长这样(最容易混的地方): #include <cmath> log2(8); // 3 底 2 log10(100); // 2 底 10 log(10); // ≈ 2.303 底 e(自然对数 ln)!不是 1 // 为什么 log(10) ≈ 2.303?因为 e^2.303 ≈ 10, // 即「e 的几次方等于 10」≈ 2.303 次
log(1) 等于多少?为什么?③ 为什么 log(100) ≈ 4.605 而不是 2?log 底是 e:e⁴·⁶⁰⁵ ≈ 100;要底 10 必须写 log10(100) = 2。把 log 当成 log10 是新手第一大坑。exp(x) = eˣ,理解复利/病毒式传播为什么是「指数」而不是「直线」。// 复利手推:本金 100 元,年利率 100% 一年计息 1 次: 100 × 2 = 200 半年计息 1 次: 100 × 1.5² = 225 一月计息 1 次: 100 × (1+1/12)¹² ≈ 252.7 一天计息 1 次: 100 × (1+1/365)³⁶⁵ ≈ 271.5 连续计息(极限):100 × e ≈ 271.8 // 计息越来越频繁,钱不会无限多,而是停在 e 倍——e 就是「连续增长的天花板」 // 病毒式传播:每人每轮再感染 2 人 轮次 1: 1 人 → 2: 2 人 → 3: 4 人 → 4: 8 人 → 5: 16 人 // 每轮人数 ×2(乘法增长),不是 +2(加法增长)——这就是「指数爆炸」 // C++:exp(x) = eˣ #include <cmath> exp(1); // ≈ 2.71828(e 本身) exp(2); // ≈ 7.389 exp(10); // ≈ 22026.5
exp(0) = ?② exp(1) + log(e) ≈ ?③ 为什么「病毒式传播」越传越快,而不是匀速?M_E,不可依赖)。可靠写法:exp(1),或手写 2.718281828459045。同理 π 用 acos(-1.0)。// 推导:设 log₃x = y,则 3ʸ = x // 两边同时取 log₂: // log₂(3ʸ) = log₂x // y × log₂3 = log₂x (指数的系数可以提到对数外面) // y = log₂x ÷ log₂3 ← 换底公式! // 手推验证:log₃9 应该 = 2(因为 3² = 9) log₂9 ≈ 3.1699 log₂3 ≈ 1.5849 3.1699 ÷ 1.5849 ≈ 2.000 ✓ // C++:用 log2 实现 log3 double log3(double x) { return log2(x) / log2(3); } log3(9); // 2 log3(27); // 3 log3(81); // 4 // 换成 log10 也一样:log3(x) = log10(x) / log10(3)
log5(x) 的函数体。② log₃27 = ?③ 为什么换底公式换成 log10 也成立(log₃x = log₁₀x ÷ log₁₀3)?return log2(x) / log2(5);(或 log10 版)。② 3(3³ = 27)。③ 推导全程只用了「a 的 b 次方的对数 = b × log a」,不依赖底是 2——换成 10(或任何 >0 且 ≠1 的底)推导照样成立,所以任意底之间都能互相换算。// 输入:n(密码位数,每位 0~9 共 10 种选法) // 输出:搜索空间 10ⁿ、等效 bit 数(log2) // 示例:输入 6 → 搜索空间 1,000,000,约 19.93 bit // 示例:输入 4 → 搜索空间 10,000,约 13.29 bit #include <iostream> #include <cmath> using namespace std; int main() { int n; cin >> n; double space = pow(10.0, n); // 10ⁿ(n ≤ 9,防止整数溢出) double bits = log2(space); // = n × log2(10) ≈ n × 3.322 cout << "搜索空间: 10^" << n << " = " << (long long)space << endl; cout << "等效安全强度约 " << bits << " bit" << endl; cout << "每多 1 位数字 ≈ 多 " << log2(10.0) << " bit(乘法增长,不是 +1)" << endl; return 0; } // 动手验证:输入 1 → 10, 3.32 bit;输入 2 → 100, 6.64 bit(翻倍,不是 +3.32 的加法)
1111₂ = 15。log(8) 和 log2(8) 各等于多少?(提示:log 的底是 e)log() 是以 e 为底的自然对数;exp(x) = eˣ,e ≈ 2.718 是复利天花板;没有 log3 就用 log₂x ÷ log₂3。