——欧拉恒等式把数学中最重要的五个常数 、、、、 用一个等式联系在一起。但如果你打开本站的 复数计算器 输入 、,你会看到同一组运算以三种形式呈现:代数形式 、极坐标形式 、欧拉形式 。
这三种形式不是“三种不同的复数”,而是同一个数学对象的三个视角。理解它们之间的关系——以及为什么计算器要同时展示三种——是复数运算的入门钥匙。
1. 三副面孔:同一个复数
复数 由实部 和虚部 组成。但“实部 + 虚部”只是复数的代数形式。同一个复数也可以用极坐标形式 描述,其中 是模长, 是辐角。或者用欧拉形式 ——极坐标的指数写法,由欧拉公式 与极坐标形式等价。
三种形式的信息量完全相同,但各有所长:
| 形式 | 表示 | 擅长 |
|---|---|---|
| 代数形式 | 加减法——实部虚部分别运算 | |
| 极坐标形式 | 几何直观——模长和角度一目了然 | |
| 欧拉形式 | 乘除法和乘方——指数律直接适用 |
本站复数计算器同时展示三种形式,因为不同的运算在不同形式下有截然不同的复杂度。
2. 代数形式:加减法的主场
复数加减法在代数形式下最自然:实部加减实部,虚部加减虚部。
计算器中对应的实现:
rows.push({
label: 'Addition z₁ + z₂',
value: fmtC(a1 + a2, b1 + b2),
});
rows.push({
label: 'Subtraction z₁ − z₂',
value: fmtC(a1 - a2, b1 - b2),
});
fmtC 是格式化函数,负责把实部和虚部拼成人类可读的字符串。它处理了三个边界情况:
- 虚部为 0:只输出实部,不显示
+ 0i。 - 实部为 0:只输出虚部,不显示
0 +。 - 虚部绝对值为 1:输出
i而非1i。
const fmtC = (re: number, im: number): string => {
const rStr = formatNumber(re);
if (Math.abs(im) < 1e-12) return rStr; // 纯实数
const sign = im >= 0 ? ' + ' : ' − ';
const absIm = Math.abs(im);
const iStr = Math.abs(absIm - 1) < 1e-12 ? 'i' : `${formatNumber(absIm)}i`;
if (Math.abs(re) < 1e-12) return im < 0 ? `−${iStr}` : iStr; // 纯虚数
return `${rStr}${sign}${iStr}`;
};
注意 1e-12 的浮点容差——不写 === 0 是因为浮点运算可能产生 级别的残余。
3. 极坐标与欧拉形式:乘除法和乘方的主场
复数乘法在代数形式下需要展开:
但在极坐标形式下,乘法变成了模长相乘、辐角相加:
计算器中乘法的实现走的是代数形式(因为用户输入的是 ),但结果可以同时从极坐标视角理解:
const mulRe = a1 * a2 - b1 * b2;
const mulIm = a1 * b2 + a2 * b1;
3.1 除法:分母有理化
复数除法需要分母有理化——乘以共轭复数消去分母的虚部:
const d2 = a2 * a2 + b2 * b2;
if (d2 !== 0) {
const divRe = (a1 * a2 + b1 * b2) / d2;
const divIm = (b1 * a2 - a1 * b2) / d2;
}
d2 !== 0 的检查防止除以零复数()。
3.2 乘方:棣莫弗定理
在代数形式下需要二项式展开,但在极坐标形式下由棣莫弗定理直接给出:
计算器的实现先转极坐标,再应用棣莫弗定理,最后转回代数形式:
if (Number.isFinite(n) && r1 > 0) {
const rn = Math.pow(r1, n);
const thn = th1 * n;
rows.push({
label: `Power z₁^${n}`,
value: fmtC(rn * Math.cos(thn), rn * Math.sin(thn)),
});
}
r1 > 0 的检查是因为 时 无定义(零复数的辐角不确定)。
3.3 共轭与倒数
共轭复数 只需翻转虚部符号。倒数 利用共轭做分母有理化:
const d1 = a1 * a1 + b1 * b1;
if (d1 !== 0) {
rows.push({
label: 'Reciprocal 1 / z₁',
value: fmtC(a1 / d1, -b1 / d1),
});
}
4. 模长与辐角:从代数到几何
模长 就是复数在复平面上到原点的距离,用 Math.hypot 计算以避免大数溢出:
const r1 = Math.hypot(a1, b1);
Math.hypot(a, b) 比 Math.sqrt(a*a + b*b) 更安全——后者在 或 很大时 可能溢出为 Infinity,而 hypot 内部做了缩放。
辐角 用 Math.atan2 计算。atan2 与 atan 的区别在于象限处理:atan(b/a) 无法区分第一象限 和第三象限 (两者 的符号相同),而 atan2(b, a) 根据两个参数的符号正确判断象限。
const th1 = Math.atan2(b1, a1);
const deg1 = (th1 * 180) / Math.PI;
辐角以弧度返回,计算器同时显示度数。
5. 复指数与复对数
欧拉公式 的推广形式 让复指数可以分解为实部贡献模长、虚部贡献旋转:
const expA = Math.exp(a1);
rows.push({
label: 'Exponential e^z₁',
value: fmtC(expA * Math.cos(b1), expA * Math.sin(b1)),
});
复对数 是复指数的逆运算,但它是多值的——辐角可以加任意 。计算器返回主值(,辐角取 ):
if (r1 > 0) {
rows.push({
label: 'Principal Logarithm Ln(z₁)',
value: fmtC(Math.log(r1), th1),
});
}
r1 > 0 的检查:零复数的对数无定义()。
6. 平方根:半角法
复数平方根 可以用棣莫弗定理取 :
const sqrtR = Math.sqrt(r1);
const sqrtTh = th1 / 2;
rows.push({
label: 'Principal Square Root √z₁',
value: fmtC(sqrtR * Math.cos(sqrtTh), sqrtR * Math.sin(sqrtTh)),
});
这是“主平方根”——另一个平方根是它的负值。每个非零复数有两个平方根,主值取辐角在 的那个。
7. 向量场:复数的另一面
复数 和 2D 向量 在表示上是同构的。本站的 向量计算器 把这层联系用到了 2D 向量场可视化中。
在 2D 绘图器 的向量场模式下,用户输入一个微分方程 ,绘图器在画布上每个网格点画一个小箭头,箭头的方向由 给出(即向量场 )。这就是方向场图,常用于可视化常微分方程的解。
向量场的渲染在 GPU 不可用时回退到 CPU 实现 renderVectorFieldCPU,在 GPU 可用时由 WebGL 片段着色器并行计算。每个像素的颜色或箭头方向由片段着色器在该像素对应的 坐标处求值 得出。
8. 工程收获
复数计算器的实现揭示了一个设计原则:同一组运算,多种表示。用户输入的是代数形式 ,但计算器同时展示极坐标和欧拉形式,因为:
- 加减法看代数形式最直观。
- 乘除法和乘方看极坐标最简洁。
- 几何理解(旋转、缩放)看极坐标最直观。
这不是过度展示——它是帮助用户建立三种表示之间的直觉联系。当你看到 的模长恰好是 、辐角恰好是 时,棣莫弗定理就不再是一个需要死记的公式,而是一个可以亲眼验证的几何事实。