From a9014ba4150b782ee10ab532752f97a7df26846e Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Tue, 25 Mar 2014 11:25:20 +1100 Subject: [PATCH] math/cmplx: define Pow(0, x) for problematic values of x. Currently it's always zero, but that is inconsistent with math.Pow and also plain wrong. This is a proposal for how it should be defined. Fixes #7583. LGTM=rsc R=golang-codereviews, iant, gobot, rsc CC=golang-codereviews https://golang.org/cl/76940044 --- src/pkg/math/cmplx/cmath_test.go | 13 +++++++++++++ src/pkg/math/cmplx/pow.go | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/pkg/math/cmplx/cmath_test.go b/src/pkg/math/cmplx/cmath_test.go index 610ca8cebb..f285646af7 100644 --- a/src/pkg/math/cmplx/cmath_test.go +++ b/src/pkg/math/cmplx/cmath_test.go @@ -656,6 +656,19 @@ func TestPolar(t *testing.T) { } } func TestPow(t *testing.T) { + // Special cases for Pow(0, c). + var zero = complex(0, 0) + zeroPowers := [][2]complex128{ + {0, 1 + 0i}, + {1.5, 0 + 0i}, + {-1.5, complex(math.Inf(0), 0)}, + {-1.5 + 1.5i, Inf()}, + } + for _, zp := range zeroPowers { + if f := Pow(zero, zp[0]); f != zp[1] { + t.Errorf("Pow(%g, %g) = %g, want %g", zero, zp[0], f, zp[1]) + } + } var a = complex(3.0, 3.0) for i := 0; i < len(vc); i++ { if f := Pow(a, vc[i]); !cSoclose(pow[i], f, 4e-15) { diff --git a/src/pkg/math/cmplx/pow.go b/src/pkg/math/cmplx/pow.go index 4dbc58398b..df0b8794ce 100644 --- a/src/pkg/math/cmplx/pow.go +++ b/src/pkg/math/cmplx/pow.go @@ -43,7 +43,25 @@ import "math" // IEEE -10,+10 30000 9.4e-15 1.5e-15 // Pow returns x**y, the base-x exponential of y. +// For generalized compatiblity with math.Pow: +// Pow(0, ±0) returns 1+0i +// Pow(0, c) for real(c)<0 returns Inf+0i if imag(c) is zero, otherwise Inf+Inf i. func Pow(x, y complex128) complex128 { + if x == 0 { // Guaranteed also true for x == -0. + r, i := real(y), imag(y) + switch { + case r == 0: + return 1 + case r < 0: + if i == 0 { + return complex(math.Inf(1), 0) + } + return Inf() + case r > 0: + return 0 + } + panic("not reached") + } modulus := Abs(x) if modulus == 0 { return complex(0, 0) -- 2.50.0