]> Cypherpunks repositories - gostls13.git/commitdiff
math/cmplx: define Pow(0, x) for problematic values of x.
authorRob Pike <r@golang.org>
Tue, 25 Mar 2014 00:25:20 +0000 (11:25 +1100)
committerRob Pike <r@golang.org>
Tue, 25 Mar 2014 00:25:20 +0000 (11:25 +1100)
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
src/pkg/math/cmplx/pow.go

index 610ca8cebb2fca06ecb7755a84006c6b0314eb42..f285646af7a8b9318b9decab32f93bde7dd6081b 100644 (file)
@@ -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) {
index 4dbc58398b4c8fcc0eda62e2e5282b292f40b375..df0b8794ce852fa8995aec7a700cd945b9812153 100644 (file)
@@ -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)