fix(bignum): ComplexMultiplier.Quo wrong result and panic for real / non-real

The a-real / b-non-real branch of Quo divided the real numerator by each
component of b independently, which is not complex division: (1+0i)/(1+i)
returned 1+1i instead of 0.5-0.5i, (1+0i)/i returned +Inf+1i, and (0+0i)/i
divided 0/0 and panicked. Use the full a*conj(b)/|b|^2 formula (the same
one the general branch uses), which reduces correctly when a is real.

Closes #577
This commit is contained in:
dualfroz committed 2026-09-02 05:04:22 +02:00
1 parent ebb3cbe701
commit 351ba05ff4
2 files changed
+57 -2

No files matched your search

+18 -2
View File
@@ -197,8 +197,24 @@ func (cEval *ComplexMultiplier) Quo(a, b, c *Complex) {
c[0].Quo(a[0], b[0])
c[1].SetFloat64(0)
} else {
c[1].Quo(a[0], b[1])
c[0].Quo(a[0], b[0])
// a is real but b is not: complex division still requires the
// full formula a/b = a*conj(b) / |b|^2. Dividing the real
// numerator by each component of b independently is incorrect
// (and divides 0/0 when a is zero).
cEval.tmp0.Mul(a[0], b[0])
cEval.tmp1.Mul(a[1], b[1])
cEval.tmp2.Mul(a[1], b[0])
cEval.tmp3.Mul(a[0], b[1])
cEval.tmp0.Add(cEval.tmp0, cEval.tmp1)
cEval.tmp1.Sub(cEval.tmp2, cEval.tmp3)
cEval.tmp2.Mul(b[0], b[0])
cEval.tmp3.Mul(b[1], b[1])
cEval.tmp2.Add(cEval.tmp2, cEval.tmp3)
c[0].Quo(cEval.tmp0, cEval.tmp2)
c[1].Quo(cEval.tmp1, cEval.tmp2)
}
} else {
if b.IsReal() {