#06 ふれてみよう高校数学 代数と式の操作

複素数とは何か

なぜ複素数が必要なのか

x2=1x^2 = -1 となる数は存在するか?」——普通の数(実数)の世界では「どんな数を2乗しても必ず0以上になる」ので、答えは「存在しない」です。

x2+1=0x^2 + 1 = 0 を解こうとすると x2=1x^2 = -1 となります。負の数の平方根は実数には存在しません。そこで数学者たちは「存在すると仮定する」という大胆な発想を採用しました。

「ないなら作ってしまえ」——これが数学の拡張の歴史です。自然数に0とマイナスを加えて整数に、整数に分数を加えて有理数に、有理数に 2\sqrt{2} などを加えて実数に——そして実数に 1\sqrt{-1} を加えて複素数になります。

i2=1i^2 = -1

この ii虚数単位と言います。i=1i = \sqrt{-1} とも書きますが、厳密には「i2=1i^2 = -1 を満たす数」と定義されます。

i¹ = i
i² = -1
i³ = -i
i⁴ = 1  ← 周期4で繰り返す
i⁵ = i  ← また i に戻る

複素数の形

複素数とは a+bia + bi の形の数です(a,ba, b は実数)。「実数部分」と「虚数部分」が合体した数です。

  • aa実部 (real part) → Re(z)\text{Re}(z)
  • bb虚部 (imaginary part) → Im(z)\text{Im}(z)
複素数実部虚部
3+2i3 + 2i32
1i-1 - i-1-1
5550
4i4i04

すべての実数は複素数の特別な場合です。数の世界が次のように広がっています:

自然数 ⊂ 整数 ⊂ 有理数 ⊂ 実数 ⊂ 複素数

複素数平面(ガウス平面)

3+2i3 + 2i という数を見せて」と言われても、普通の数直線(1次元)では見せられません。実部と虚部の2つの成分があるので、2次元の平面が必要です。

複素数 z=a+biz = a + bi を、横軸(実軸)aa、縦軸(虚軸)bb の平面上の点として描けます。これを複素数平面またはガウス平面と言います。

下のデモでマウスを動かすと、複素数 zz が変わり、絶対値 z|z|偏角 arg(z)\arg(z) がリアルタイムで表示されます。

複素数平面:マウスを動かして複素数の位置を変え、|z| と arg(z) を確認しよう
function loop() {
ctx.clearRect(0, 0, W, H);

var cx = W / 2, cy = H / 2;
var scale = 60;

// Grid
ctx.strokeStyle = '#1e293b';
ctx.lineWidth = 1;
for (var gx = -4; gx <= 4; gx++) {
  ctx.beginPath();
  ctx.moveTo(cx + gx * scale, 0);
  ctx.lineTo(cx + gx * scale, H);
  ctx.stroke();
}
for (var gy = -3; gy <= 3; gy++) {
  ctx.beginPath();
  ctx.moveTo(0, cy + gy * scale);
  ctx.lineTo(W, cy + gy * scale);
  ctx.stroke();
}

// Axes
ctx.strokeStyle = '#475569';
ctx.lineWidth = 1.5;
ctx.beginPath(); ctx.moveTo(0, cy); ctx.lineTo(W, cy); ctx.stroke();
ctx.beginPath(); ctx.moveTo(cx, 0); ctx.lineTo(cx, H); ctx.stroke();

// Axis labels
ctx.fillStyle = '#64748b';
ctx.font = '12px monospace';
ctx.textAlign = 'center';
ctx.fillText('実軸 (Re)', W - 30, cy - 8);
ctx.textAlign = 'left';
ctx.fillText('虚軸 (Im)', cx + 6, 14);

for (var n = -4; n <= 4; n++) {
  if (n === 0) continue;
  ctx.fillStyle = '#475569';
  ctx.font = '11px monospace';
  ctx.textAlign = 'center';
  ctx.fillText(n, cx + n * scale, cy + 14);
  ctx.fillText(n + 'i', cx + 6, cy - n * scale + 4);
}
ctx.fillText('O', cx - 12, cy + 14);

// Complex number z from mouse
var a = (mx - cx) / scale;
var b = -(my - cy) / scale;
var px = cx + a * scale;
var py = cy - b * scale;
var modz = Math.sqrt(a*a + b*b);
var argz = Math.atan2(b, a) * 180 / Math.PI;

// Angle arc
if (modz > 0.2) {
  ctx.strokeStyle = '#fbbf24';
  ctx.lineWidth = 1.5;
  ctx.beginPath();
  ctx.arc(cx, cy, 30, -Math.atan2(b, a), 0, b >= 0);
  ctx.stroke();
  var midAngle = Math.atan2(b, a) / 2;
  ctx.fillStyle = '#fbbf24';
  ctx.font = '11px monospace';
  ctx.textAlign = 'center';
  ctx.fillText('θ', cx + 40 * Math.cos(midAngle), cy - 40 * Math.sin(midAngle));
}

// Line from origin to z
ctx.strokeStyle = '#3b82f6';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.lineTo(px, py);
ctx.stroke();

// Dashed projections
ctx.strokeStyle = '#475569';
ctx.lineWidth = 1;
ctx.setLineDash([4, 4]);
ctx.beginPath(); ctx.moveTo(px, py); ctx.lineTo(px, cy); ctx.stroke();
ctx.beginPath(); ctx.moveTo(px, py); ctx.lineTo(cx, py); ctx.stroke();
ctx.setLineDash([]);

// Point z
ctx.fillStyle = '#3b82f6';
ctx.beginPath();
ctx.arc(px, py, 7, 0, Math.PI * 2);
ctx.fill();
ctx.strokeStyle = '#93c5fd';
ctx.lineWidth = 2;
ctx.stroke();

// Label z
ctx.fillStyle = '#e2e8f0';
ctx.font = 'bold 13px monospace';
ctx.textAlign = px > cx ? 'left' : 'right';
var bSign = b >= 0 ? '+' : '-';
ctx.fillText('z = ' + a.toFixed(1) + ' ' + bSign + ' ' + Math.abs(b).toFixed(1) + 'i', px + (px>cx?10:-10), py - 10);

// Info panel
ctx.fillStyle = '#0f172a';
ctx.fillRect(10, 10, 200, 80);
ctx.strokeStyle = '#334155';
ctx.lineWidth = 1;
ctx.strokeRect(10, 10, 200, 80);

ctx.fillStyle = '#e2e8f0';
ctx.font = '13px monospace';
ctx.textAlign = 'left';
ctx.fillText('Re(z) = ' + a.toFixed(2), 20, 32);
ctx.fillText('Im(z) = ' + b.toFixed(2), 20, 50);
ctx.fillStyle = '#fbbf24';
ctx.fillText('|z| = ' + modz.toFixed(3), 20, 68);
ctx.fillStyle = '#22c55e';
ctx.fillText('arg(z) = ' + argz.toFixed(1) + '°', 20, 86);

requestAnimationFrame(loop);
}
loop();

絶対値と偏角

複素数 z=a+biz = a + bi について:

絶対値(モジュラス):原点からの距離——ピタゴラスの定理そのままです。

|z| = √(a² + b²)

偏角(アーギュメント):実軸からの角度——「どの方向を向いているか」

arg(z) = θ  (tan θ = b/a)

z=3+4iz = 3 + 4i の場合:「3, 4, 5の直角三角形」なのでパッとわかります。

z=9+16=25=5|z| = \sqrt{9 + 16} = \sqrt{25} = 5

arg(z)=arctan(4/3)53.1°\arg(z) = \arctan(4/3) \approx 53.1°


複素共役

z=a+biz = a + bi共役複素数zˉ=abi\bar{z} = a - bi です——「虚部の符号だけを変えた数」です。

複素平面上では実軸に関して対称な点になります。「鏡に映したような位置」と覚えると直感的です。

重要な性質:

z + z̄ = 2a      (実部の2倍)
z · z̄ = a² + b² = |z|²
z = z̄ ⟺ z は実数

共役を使うと有理化と同様の操作ができます。「分母に複素数があるとき、共役を掛けて実数にする」——前回の有理化と同じ発想です:

1a+bi=abi(a+bi)(abi)=abia2+b2\dfrac{1}{a + bi} = \dfrac{a - bi}{(a+bi)(a-bi)} = \dfrac{a - bi}{a^2 + b^2}


複素共役の可視化

複素数 z とその共役 z̄:実軸に関して対称。マウスで z の位置を変える
function loop() {
ctx.clearRect(0, 0, W, H);

var cx = W/2, cy = H/2;
var scale = 55;

// axes
ctx.strokeStyle = '#334155';
ctx.lineWidth = 1.5;
ctx.beginPath(); ctx.moveTo(0, cy); ctx.lineTo(W, cy); ctx.stroke();
ctx.beginPath(); ctx.moveTo(cx, 0); ctx.lineTo(cx, H); ctx.stroke();

ctx.fillStyle = '#475569';
ctx.font = '12px monospace';
ctx.textAlign = 'center';
ctx.fillText('実軸', W-20, cy-8);
ctx.textAlign = 'left';
ctx.fillText('虚軸', cx+6, 14);

var a = (mx - cx) / scale;
var b = -(my - cy) / scale;

var zx = cx + a * scale;
var zy = cy - b * scale;
var conjx = cx + a * scale;
var conjy = cy + b * scale;

// Line to z
ctx.strokeStyle = '#3b82f6';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.lineTo(zx, zy);
ctx.stroke();

// Line to conjugate
ctx.strokeStyle = '#ef4444';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.lineTo(conjx, conjy);
ctx.stroke();

// Symmetry dashed line
ctx.strokeStyle = '#fbbf24';
ctx.lineWidth = 1;
ctx.setLineDash([5, 5]);
ctx.beginPath();
ctx.moveTo(zx, zy);
ctx.lineTo(conjx, conjy);
ctx.stroke();
ctx.setLineDash([]);

// Points
ctx.fillStyle = '#3b82f6';
ctx.beginPath(); ctx.arc(zx, zy, 7, 0, Math.PI*2); ctx.fill();
ctx.fillStyle = '#ef4444';
ctx.beginPath(); ctx.arc(conjx, conjy, 7, 0, Math.PI*2); ctx.fill();

// Labels
ctx.font = 'bold 13px monospace';
ctx.fillStyle = '#93c5fd';
ctx.textAlign = a >= 0 ? 'left' : 'right';
var sign = b >= 0 ? '+' : '-';
ctx.fillText('z = ' + a.toFixed(1) + ' ' + sign + ' ' + Math.abs(b).toFixed(1) + 'i', zx+(a>=0?10:-10), zy-8);
ctx.fillStyle = '#fca5a5';
sign = b >= 0 ? '-' : '+';
ctx.fillText('z̄ = ' + a.toFixed(1) + ' ' + sign + ' ' + Math.abs(b).toFixed(1) + 'i', conjx+(a>=0?10:-10), conjy+18);

ctx.fillStyle = '#fbbf24';
ctx.font = '12px monospace';
ctx.textAlign = 'center';
ctx.fillText('z · z̄ = |z|² = ' + (a*a+b*b).toFixed(2), W/2, 285);

requestAnimationFrame(loop);
}
loop();

極形式の予告

複素数は直交座標形式 a+bia + bi だけでなく、極形式 r(cosθ+isinθ)=reiθr(\cos\theta + i\sin\theta) = re^{i\theta} でも表せます。

z=r(cosθ+isinθ)z = r(\cos\theta + i\sin\theta)

ここで r=zr = |z|(原点からの距離)、θ=arg(z)\theta = \arg(z)(向きの角度)。この表現は次回の「複素数の四則演算」で威力を発揮します。特に乗算が回転と拡大縮小として理解できるようになります。


まとめ

  • i2=1i^2 = -1 を定義することで複素数 z=a+biz = a + bi が誕生——「ない数を作る」という数学の拡張の歴史
  • 複素数平面(ガウス平面)では zz を座標点として視覚化できる——実部が横、虚部が縦
  • 絶対値 z=a2+b2|z| = \sqrt{a^2+b^2}(原点からの距離——ピタゴラスの定理)
  • 偏角 arg(z)=θ\arg(z) = \theta(実軸からの角度——どの方向を向いているか)
  • 共役 zˉ=abi\bar{z} = a - bi(実軸に対称)、zzˉ=z2z\bar{z} = |z|^2——「鏡に映した数」

次回は複素数の四則演算を学びます。特に乗算が回転と拡大縮小に相当するという、幾何学的に美しい性質を探ります。