Commit f5e89c22 authored by Ian Lance Taylor's avatar Ian Lance Taylor Committed by Brad Fitzpatrick

Revert "math/cmplx: handle special cases"

This reverts CL 169501.

Reason for revert: The new tests fail at least on s390x and MIPS. This is likely a minor bug in the compiler or runtime. But this point in the release cycle is not the time to debug these details, which are unlikely to be new. Let's try again for 1.15.

Updates #29320
Fixes #35443

Change-Id: I2218b2083f8974b57d528e3742524393fc72b355
Reviewed-on: https://go-review.googlesource.com/c/go/+/206037
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: default avatarBryan C. Mills <bcmills@google.com>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent e038c7e4
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Package cmplx provides basic constants and mathematical functions for // Package cmplx provides basic constants and mathematical functions for
// complex numbers. Special case handling conforms to the C99 standard // complex numbers.
// Annex G IEC 60559-compatible complex arithmetic.
package cmplx package cmplx
import "math" import "math"
......
...@@ -49,31 +49,8 @@ import "math" ...@@ -49,31 +49,8 @@ import "math"
// Asin returns the inverse sine of x. // Asin returns the inverse sine of x.
func Asin(x complex128) complex128 { func Asin(x complex128) complex128 {
switch re, im := real(x), imag(x); { if imag(x) == 0 && math.Abs(real(x)) <= 1 {
case im == 0 && math.Abs(re) <= 1: return complex(math.Asin(real(x)), imag(x))
return complex(math.Asin(re), im)
case re == 0 && math.Abs(im) <= 1:
return complex(re, math.Asinh(im))
case math.IsNaN(im):
switch {
case re == 0:
return complex(re, math.NaN())
case math.IsInf(re, 0):
return complex(math.NaN(), re)
default:
return NaN()
}
case math.IsInf(im, 0):
switch {
case math.IsNaN(re):
return x
case math.IsInf(re, 0):
return complex(math.Copysign(math.Pi/4, re), im)
default:
return complex(math.Copysign(0, re), im)
}
case math.IsInf(re, 0):
return complex(math.Copysign(math.Pi/2, re), math.Copysign(re, im))
} }
ct := complex(-imag(x), real(x)) // i * x ct := complex(-imag(x), real(x)) // i * x
xx := x * x xx := x * x
...@@ -85,31 +62,8 @@ func Asin(x complex128) complex128 { ...@@ -85,31 +62,8 @@ func Asin(x complex128) complex128 {
// Asinh returns the inverse hyperbolic sine of x. // Asinh returns the inverse hyperbolic sine of x.
func Asinh(x complex128) complex128 { func Asinh(x complex128) complex128 {
switch re, im := real(x), imag(x); { if imag(x) == 0 && math.Abs(real(x)) <= 1 {
case im == 0 && math.Abs(re) <= 1: return complex(math.Asinh(real(x)), imag(x))
return complex(math.Asinh(re), im)
case re == 0 && math.Abs(im) <= 1:
return complex(re, math.Asin(im))
case math.IsInf(re, 0):
switch {
case math.IsInf(im, 0):
return complex(re, math.Copysign(math.Pi/4, im))
case math.IsNaN(im):
return x
default:
return complex(re, math.Copysign(0.0, im))
}
case math.IsNaN(re):
switch {
case im == 0:
return x
case math.IsInf(im, 0):
return complex(im, re)
default:
return NaN()
}
case math.IsInf(im, 0):
return complex(math.Copysign(im, re), math.Copysign(math.Pi/2, im))
} }
xx := x * x xx := x * x
x1 := complex(1+real(xx), imag(xx)) // 1 + x*x x1 := complex(1+real(xx), imag(xx)) // 1 + x*x
...@@ -137,9 +91,6 @@ func Acos(x complex128) complex128 { ...@@ -137,9 +91,6 @@ func Acos(x complex128) complex128 {
// Acosh returns the inverse hyperbolic cosine of x. // Acosh returns the inverse hyperbolic cosine of x.
func Acosh(x complex128) complex128 { func Acosh(x complex128) complex128 {
if x == 0 {
return complex(0, math.Copysign(math.Pi/2, imag(x)))
}
w := Acos(x) w := Acos(x)
if imag(w) <= 0 { if imag(w) <= 0 {
return complex(-imag(w), real(w)) // i * w return complex(-imag(w), real(w)) // i * w
...@@ -182,17 +133,6 @@ func Acosh(x complex128) complex128 { ...@@ -182,17 +133,6 @@ func Acosh(x complex128) complex128 {
// Atan returns the inverse tangent of x. // Atan returns the inverse tangent of x.
func Atan(x complex128) complex128 { func Atan(x complex128) complex128 {
switch re, im := real(x), imag(x); {
case im == 0:
return complex(math.Atan(re), im)
case re == 0 && math.Abs(im) <= 1:
return complex(re, math.Atanh(im))
case math.IsInf(im, 0) || math.IsInf(re, 0):
if math.IsNaN(re) {
return complex(math.NaN(), math.Copysign(0, im))
}
return complex(math.Copysign(math.Pi/2, re), math.Copysign(0, im))
}
x2 := real(x) * real(x) x2 := real(x) * real(x)
a := 1 - x2 - imag(x)*imag(x) a := 1 - x2 - imag(x)*imag(x)
if a == 0 { if a == 0 {
......
...@@ -291,190 +291,48 @@ var tanh = []complex128{ ...@@ -291,190 +291,48 @@ var tanh = []complex128{
(-1.0000000491604982429364892e+00 - 2.901873195374433112227349e-08i), (-1.0000000491604982429364892e+00 - 2.901873195374433112227349e-08i),
} }
// special cases conform to C99 standard appendix G.6 Complex arithmetic // special cases
var inf, nan = math.Inf(1), math.NaN()
var vcAbsSC = []complex128{ var vcAbsSC = []complex128{
NaN(), NaN(),
} }
var absSC = []float64{ var absSC = []float64{
math.NaN(), math.NaN(),
} }
var acosSC = []struct { var vcAcosSC = []complex128{
in, NaN(),
want complex128 }
}{ var acosSC = []complex128{
// G.6.1.1 NaN(),
{complex(zero, zero), }
complex(math.Pi/2, -zero)}, var vcAcoshSC = []complex128{
{complex(-zero, zero), NaN(),
complex(math.Pi/2, -zero)}, }
{complex(zero, nan), var acoshSC = []complex128{
complex(math.Pi/2, nan)}, NaN(),
{complex(-zero, nan), }
complex(math.Pi/2, nan)}, var vcAsinSC = []complex128{
{complex(1.0, inf), NaN(),
complex(math.Pi/2, -inf)}, }
{complex(1.0, nan), var asinSC = []complex128{
NaN()}, NaN(),
{complex(-inf, 1.0), }
complex(math.Pi, -inf)}, var vcAsinhSC = []complex128{
{complex(inf, 1.0), NaN(),
complex(0.0, -inf)}, }
{complex(-inf, inf), var asinhSC = []complex128{
complex(3*math.Pi/4, -inf)}, NaN(),
{complex(inf, inf), }
complex(math.Pi/4, -inf)}, var vcAtanSC = []complex128{
{complex(inf, nan), NaN(),
complex(nan, -inf)}, // imaginary sign unspecified }
{complex(-inf, nan), var atanSC = []complex128{
complex(nan, inf)}, // imaginary sign unspecified NaN(),
{complex(nan, 1.0), }
NaN()}, var vcAtanhSC = []complex128{
{complex(nan, inf), NaN(),
complex(nan, -inf)}, }
{NaN(), var atanhSC = []complex128{
NaN()}, NaN(),
}
var acoshSC = []struct {
in,
want complex128
}{
// G.6.2.1
{complex(zero, zero),
complex(zero, math.Pi/2)},
{complex(-zero, zero),
complex(zero, math.Pi/2)},
{complex(1.0, inf),
complex(inf, math.Pi/2)},
{complex(1.0, nan),
NaN()},
{complex(-inf, 1.0),
complex(inf, math.Pi)},
{complex(inf, 1.0),
complex(inf, zero)},
{complex(-inf, inf),
complex(inf, 3*math.Pi/4)},
{complex(inf, inf),
complex(inf, math.Pi/4)},
{complex(inf, nan),
complex(inf, nan)},
{complex(-inf, nan),
complex(inf, nan)},
{complex(nan, 1.0),
NaN()},
{complex(nan, inf),
complex(inf, nan)},
{NaN(),
NaN()},
}
var asinSC = []struct {
in,
want complex128
}{
// Derived from Asin(z) = -i * Asinh(i * z), G.6 #7
{complex(zero, zero),
complex(zero, zero)},
{complex(1.0, inf),
complex(0, inf)},
{complex(1.0, nan),
NaN()},
{complex(inf, 1),
complex(math.Pi/2, inf)},
{complex(inf, inf),
complex(math.Pi/4, inf)},
{complex(inf, nan),
complex(nan, inf)}, // imaginary sign unspecified
{complex(nan, zero),
NaN()},
{complex(nan, 1),
NaN()},
{complex(nan, inf),
complex(nan, inf)},
{NaN(),
NaN()},
}
var asinhSC = []struct {
in,
want complex128
}{
// G.6.2.2
{complex(zero, zero),
complex(zero, zero)},
{complex(1.0, inf),
complex(inf, math.Pi/2)},
{complex(1.0, nan),
NaN()},
{complex(inf, 1.0),
complex(inf, zero)},
{complex(inf, inf),
complex(inf, math.Pi/4)},
{complex(inf, nan),
complex(inf, nan)},
{complex(nan, zero),
complex(nan, zero)},
{complex(nan, 1.0),
NaN()},
{complex(nan, inf),
complex(inf, nan)}, // sign of real part unspecified
{NaN(),
NaN()},
}
var atanSC = []struct {
in,
want complex128
}{
// Derived from Atan(z) = -i * Atanh(i * z), G.6 #7
{complex(0, zero),
complex(0, zero)},
{complex(0, nan),
NaN()},
{complex(1.0, zero),
complex(math.Pi/4, zero)},
{complex(1.0, inf),
complex(math.Pi/2, zero)},
{complex(1.0, nan),
NaN()},
{complex(inf, 1),
complex(math.Pi/2, zero)},
{complex(inf, inf),
complex(math.Pi/2, zero)},
{complex(inf, nan),
complex(math.Pi/2, zero)},
{complex(nan, 1),
NaN()},
{complex(nan, inf),
complex(nan, zero)},
{NaN(),
NaN()},
}
var atanhSC = []struct {
in,
want complex128
}{
// G.6.2.3
{complex(zero, zero),
complex(zero, zero)},
{complex(zero, nan),
complex(zero, nan)},
{complex(1.0, zero),
complex(inf, zero)},
{complex(1.0, inf),
complex(0, math.Pi/2)},
{complex(1.0, nan),
NaN()},
{complex(inf, 1.0),
complex(zero, math.Pi/2)},
{complex(inf, inf),
complex(zero, math.Pi/2)},
{complex(inf, nan),
complex(0, nan)},
{complex(nan, 1.0),
NaN()},
{complex(nan, inf),
complex(zero, math.Pi/2)}, // sign of real part not specified.
{NaN(),
NaN()},
} }
var vcConjSC = []complex128{ var vcConjSC = []complex128{
NaN(), NaN(),
...@@ -482,105 +340,23 @@ var vcConjSC = []complex128{ ...@@ -482,105 +340,23 @@ var vcConjSC = []complex128{
var conjSC = []complex128{ var conjSC = []complex128{
NaN(), NaN(),
} }
var cosSC = []struct { var vcCosSC = []complex128{
in, NaN(),
want complex128 }
}{ var cosSC = []complex128{
// Derived from Cos(z) = Cosh(i * z), G.6 #7 NaN(),
{complex(zero, zero), }
complex(1.0, -zero)}, var vcCoshSC = []complex128{
{complex(zero, inf), NaN(),
complex(inf, -zero)}, }
{complex(zero, nan), var coshSC = []complex128{
complex(nan, zero)}, // imaginary sign unspecified NaN(),
{complex(1.0, inf), }
complex(inf, -inf)}, var vcExpSC = []complex128{
{complex(1.0, nan), NaN(),
NaN()}, }
{complex(inf, zero), var expSC = []complex128{
complex(nan, -zero)}, NaN(),
{complex(inf, 1.0),
NaN()},
{complex(inf, inf),
complex(inf, nan)}, // real sign unspecified
{complex(inf, nan),
NaN()},
{complex(nan, zero),
complex(nan, -zero)}, // imaginary sign unspecified
{complex(nan, 1.0),
NaN()},
{complex(nan, inf),
complex(inf, nan)},
{NaN(),
NaN()},
}
var coshSC = []struct {
in,
want complex128
}{
// G.6.2.4
{complex(zero, zero),
complex(1.0, zero)},
{complex(zero, inf),
complex(nan, zero)}, // imaginary sign unspecified
{complex(zero, nan),
complex(nan, zero)}, // imaginary sign unspecified
{complex(1.0, inf),
NaN()},
{complex(1.0, nan),
NaN()},
{complex(inf, zero),
complex(inf, zero)},
{complex(inf, 1.0),
complex(inf*math.Cos(1.0), inf*math.Sin(1.0))}, // +inf cis(y)
{complex(inf, inf),
complex(inf, nan)}, // real sign unspecified
{complex(inf, nan),
complex(inf, nan)},
{complex(nan, zero),
complex(nan, zero)}, // imaginary sign unspecified
{complex(nan, 1.0),
NaN()},
{complex(nan, inf),
NaN()},
{NaN(),
NaN()},
}
var expSC = []struct {
in,
want complex128
}{
// G.6.3.1
{complex(zero, zero),
complex(1.0, zero)},
{complex(-zero, zero),
complex(1.0, zero)},
{complex(1.0, inf),
NaN()},
{complex(1.0, nan),
NaN()},
{complex(inf, zero),
complex(inf, zero)},
{complex(-inf, 1.0),
complex(math.Copysign(0.0, math.Cos(1.0)), math.Copysign(0.0, math.Sin(1.0)))}, // +0 cis(y)
{complex(inf, 1.0),
complex(inf*math.Cos(1.0), inf*math.Sin(1.0))}, // +inf cis(y)
{complex(-inf, inf),
complex(zero, zero)}, // real and imaginary sign unspecified
{complex(inf, inf),
complex(inf, nan)}, // real sign unspecified
{complex(-inf, nan),
complex(zero, zero)}, // real and imaginary sign unspecified
{complex(inf, nan),
complex(inf, nan)}, // real sign unspecified
{complex(nan, zero),
complex(nan, zero)},
{complex(nan, 1.0),
NaN()},
{complex(nan, inf),
NaN()},
{NaN(),
NaN()},
} }
var vcIsNaNSC = []complex128{ var vcIsNaNSC = []complex128{
complex(math.Inf(-1), math.Inf(-1)), complex(math.Inf(-1), math.Inf(-1)),
...@@ -604,70 +380,17 @@ var isNaNSC = []bool{ ...@@ -604,70 +380,17 @@ var isNaNSC = []bool{
false, false,
true, true,
} }
var vcLogSC = []complex128{
var logSC = []struct { NaN(),
in, }
want complex128 var logSC = []complex128{
}{ NaN(),
// G.6.3.2 }
{complex(zero, zero), var vcLog10SC = []complex128{
complex(-inf, zero)}, NaN(),
{complex(-zero, zero), }
complex(-inf, math.Pi)}, var log10SC = []complex128{
{complex(1.0, inf), NaN(),
complex(inf, math.Pi/2)},
{complex(1.0, nan),
NaN()},
{complex(-inf, 1.0),
complex(inf, math.Pi)},
{complex(inf, 1.0),
complex(inf, 0.0)},
{complex(-inf, inf),
complex(inf, 3*math.Pi/4)},
{complex(inf, inf),
complex(inf, math.Pi/4)},
{complex(-inf, nan),
complex(inf, nan)},
{complex(inf, nan),
complex(inf, nan)},
{complex(nan, 1.0),
NaN()},
{complex(nan, inf),
complex(inf, nan)},
{NaN(),
NaN()},
}
var log10SC = []struct {
in,
want complex128
}{
// derived from Log special cases via Log10(x) = math.Log10E*Log(x)
{complex(zero, zero),
complex(-inf, zero)},
{complex(-zero, zero),
complex(-inf, float64(math.Log10E)*float64(math.Pi))},
{complex(1.0, inf),
complex(inf, float64(math.Log10E)*float64(math.Pi/2))},
{complex(1.0, nan),
NaN()},
{complex(-inf, 1.0),
complex(inf, float64(math.Log10E)*float64(math.Pi))},
{complex(inf, 1.0),
complex(inf, 0.0)},
{complex(-inf, inf),
complex(inf, float64(math.Log10E)*float64(3*math.Pi/4))},
{complex(inf, inf),
complex(inf, float64(math.Log10E)*float64(math.Pi/4))},
{complex(-inf, nan),
complex(inf, nan)},
{complex(inf, nan),
complex(inf, nan)},
{complex(nan, 1.0),
NaN()},
{complex(nan, inf),
complex(inf, nan)},
{NaN(),
NaN()},
} }
var vcPolarSC = []complex128{ var vcPolarSC = []complex128{
NaN(), NaN(),
...@@ -683,153 +406,35 @@ var powSC = []complex128{ ...@@ -683,153 +406,35 @@ var powSC = []complex128{
NaN(), NaN(),
NaN(), NaN(),
} }
var sinSC = []struct { var vcSinSC = []complex128{
in, NaN(),
want complex128
}{
// Derived from Sin(z) = -i * Sinh(i * z), G.6 #7
{complex(zero, zero),
complex(zero, zero)},
{complex(zero, inf),
complex(zero, inf)},
{complex(zero, nan),
complex(zero, nan)},
{complex(1.0, inf),
complex(inf, inf)},
{complex(1.0, nan),
NaN()},
{complex(inf, zero),
complex(nan, zero)},
{complex(inf, 1.0),
NaN()},
{complex(inf, inf),
complex(nan, inf)},
{complex(inf, nan),
NaN()},
{complex(nan, zero),
complex(nan, zero)},
{complex(nan, 1.0),
NaN()},
{complex(nan, inf),
complex(nan, inf)},
{NaN(),
NaN()},
} }
var sinSC = []complex128{
var sinhSC = []struct { NaN(),
in,
want complex128
}{
// G.6.2.5
{complex(zero, zero),
complex(zero, zero)},
{complex(zero, inf),
complex(zero, nan)}, // real sign unspecified
{complex(zero, nan),
complex(zero, nan)}, // real sign unspecified
{complex(1.0, inf),
NaN()},
{complex(1.0, nan),
NaN()},
{complex(inf, zero),
complex(inf, zero)},
{complex(inf, 1.0),
complex(inf*math.Cos(1.0), inf*math.Sin(1.0))}, // +inf cis(y)
{complex(inf, inf),
complex(inf, nan)}, // real sign unspecified
{complex(inf, nan),
complex(inf, nan)}, // real sign unspecified
{complex(nan, zero),
complex(nan, zero)},
{complex(nan, 1.0),
NaN()},
{complex(nan, inf),
NaN()},
{NaN(),
NaN()},
} }
var vcSinhSC = []complex128{
var sqrtSC = []struct { NaN(),
in, }
want complex128 var sinhSC = []complex128{
}{ NaN(),
// G.6.4.2 }
{complex(zero, zero), var vcSqrtSC = []complex128{
complex(zero, zero)}, NaN(),
{complex(-zero, zero), }
complex(zero, zero)}, var sqrtSC = []complex128{
{complex(1.0, inf), NaN(),
complex(inf, inf)}, }
{complex(nan, inf), var vcTanSC = []complex128{
complex(inf, inf)}, NaN(),
{complex(1.0, nan), }
NaN()}, var tanSC = []complex128{
{complex(-inf, 1.0), NaN(),
complex(zero, inf)}, }
{complex(inf, 1.0), var vcTanhSC = []complex128{
complex(inf, zero)}, NaN(),
{complex(-inf, nan), }
complex(nan, inf)}, // imaginary sign unspecified var tanhSC = []complex128{
{complex(inf, nan), NaN(),
complex(inf, nan)},
{complex(nan, 1.0),
NaN()},
{NaN(),
NaN()},
}
var tanSC = []struct {
in,
want complex128
}{
// Derived from Tan(z) = -i * Tanh(i * z), G.6 #7
{complex(zero, zero),
complex(zero, zero)},
{complex(zero, nan),
complex(zero, nan)},
{complex(1.0, inf),
complex(zero, 1.0)},
{complex(1.0, nan),
NaN()},
{complex(inf, 1.0),
NaN()},
{complex(inf, inf),
complex(zero, 1.0)},
{complex(inf, nan),
NaN()},
{complex(nan, zero),
NaN()},
{complex(nan, 1.0),
NaN()},
{complex(nan, inf),
complex(zero, 1.0)},
{NaN(),
NaN()},
}
var tanhSC = []struct {
in,
want complex128
}{
// G.6.2.6
{complex(zero, zero),
complex(zero, zero)},
{complex(1.0, inf),
NaN()},
{complex(1.0, nan),
NaN()},
{complex(inf, 1.0),
complex(1.0, math.Copysign(0.0, math.Sin(2*1.0)))}, // 1 + i 0 sin(2y)
{complex(inf, inf),
complex(1.0, zero)}, // imaginary sign unspecified
{complex(inf, nan),
complex(1.0, zero)}, // imaginary sign unspecified
{complex(nan, zero),
complex(nan, zero)},
{complex(nan, 1.0),
NaN()},
{complex(nan, inf),
NaN()},
{NaN(),
NaN()},
} }
// branch cut continuity checks // branch cut continuity checks
...@@ -891,7 +496,13 @@ func cTolerance(a, b complex128, e float64) bool { ...@@ -891,7 +496,13 @@ func cTolerance(a, b complex128, e float64) bool {
func cSoclose(a, b complex128, e float64) bool { return cTolerance(a, b, e) } func cSoclose(a, b complex128, e float64) bool { return cTolerance(a, b, e) }
func cVeryclose(a, b complex128) bool { return cTolerance(a, b, 4e-16) } func cVeryclose(a, b complex128) bool { return cTolerance(a, b, 4e-16) }
func cAlike(a, b complex128) bool { func cAlike(a, b complex128) bool {
return alike(real(a), real(b)) && alike(imag(a), imag(b)) switch {
case IsNaN(a) && IsNaN(b):
return true
case a == b:
return math.Signbit(real(a)) == math.Signbit(real(b)) && math.Signbit(imag(a)) == math.Signbit(imag(b))
}
return false
} }
func TestAbs(t *testing.T) { func TestAbs(t *testing.T) {
...@@ -912,13 +523,9 @@ func TestAcos(t *testing.T) { ...@@ -912,13 +523,9 @@ func TestAcos(t *testing.T) {
t.Errorf("Acos(%g) = %g, want %g", vc[i], f, acos[i]) t.Errorf("Acos(%g) = %g, want %g", vc[i], f, acos[i])
} }
} }
for _, v := range acosSC { for i := 0; i < len(vcAcosSC); i++ {
if f := Acos(v.in); !cAlike(v.want, f) { if f := Acos(vcAcosSC[i]); !cAlike(acosSC[i], f) {
t.Errorf("Acos(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Acos(%g) = %g, want %g", vcAcosSC[i], f, acosSC[i])
}
// Acos(Conj(z)) == Conj(Acos(z))
if f := Acos(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Acos(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
} }
} }
for _, pt := range branchPoints { for _, pt := range branchPoints {
...@@ -933,15 +540,10 @@ func TestAcosh(t *testing.T) { ...@@ -933,15 +540,10 @@ func TestAcosh(t *testing.T) {
t.Errorf("Acosh(%g) = %g, want %g", vc[i], f, acosh[i]) t.Errorf("Acosh(%g) = %g, want %g", vc[i], f, acosh[i])
} }
} }
for _, v := range acoshSC { for i := 0; i < len(vcAcoshSC); i++ {
if f := Acosh(v.in); !cAlike(v.want, f) { if f := Acosh(vcAcoshSC[i]); !cAlike(acoshSC[i], f) {
t.Errorf("Acosh(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Acosh(%g) = %g, want %g", vcAcoshSC[i], f, acoshSC[i])
} }
// Acosh(Conj(z)) == Conj(Acosh(z))
if f := Acosh(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Acosh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
}
} }
for _, pt := range branchPoints { for _, pt := range branchPoints {
if f0, f1 := Acosh(pt[0]), Acosh(pt[1]); !cVeryclose(f0, f1) { if f0, f1 := Acosh(pt[0]), Acosh(pt[1]); !cVeryclose(f0, f1) {
...@@ -955,21 +557,9 @@ func TestAsin(t *testing.T) { ...@@ -955,21 +557,9 @@ func TestAsin(t *testing.T) {
t.Errorf("Asin(%g) = %g, want %g", vc[i], f, asin[i]) t.Errorf("Asin(%g) = %g, want %g", vc[i], f, asin[i])
} }
} }
for _, v := range asinSC { for i := 0; i < len(vcAsinSC); i++ {
if f := Asin(v.in); !cAlike(v.want, f) { if f := Asin(vcAsinSC[i]); !cAlike(asinSC[i], f) {
t.Errorf("Asin(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Asin(%g) = %g, want %g", vcAsinSC[i], f, asinSC[i])
}
if cAlike(-v.in, Conj(v.in)) && !cAlike(-v.want, Conj(v.want)) {
// The following conditions can't simultaneously be satisfied for this input.
continue
}
// Asin(Conj(z)) == Asin(Sinh(z))
if f := Asin(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Asin(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
}
// Asin(-z) == -Asin(z)
if f := Asin(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) {
t.Errorf("Asin(%g) = %g, want %g", -v.in, f, -v.want)
} }
} }
for _, pt := range branchPoints { for _, pt := range branchPoints {
...@@ -984,21 +574,9 @@ func TestAsinh(t *testing.T) { ...@@ -984,21 +574,9 @@ func TestAsinh(t *testing.T) {
t.Errorf("Asinh(%g) = %g, want %g", vc[i], f, asinh[i]) t.Errorf("Asinh(%g) = %g, want %g", vc[i], f, asinh[i])
} }
} }
for _, v := range asinhSC { for i := 0; i < len(vcAsinhSC); i++ {
if f := Asinh(v.in); !cAlike(v.want, f) { if f := Asinh(vcAsinhSC[i]); !cAlike(asinhSC[i], f) {
t.Errorf("Asinh(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Asinh(%g) = %g, want %g", vcAsinhSC[i], f, asinhSC[i])
}
if cAlike(-v.in, Conj(v.in)) && !cAlike(-v.want, Conj(v.want)) {
// The following conditions can't simultaneously be satisfied for this input.
continue
}
// Asinh(Conj(z)) == Asinh(Sinh(z))
if f := Asinh(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Asinh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
}
// Asinh(-z) == -Asinh(z)
if f := Asinh(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) {
t.Errorf("Asinh(%g) = %g, want %g", -v.in, f, -v.want)
} }
} }
for _, pt := range branchPoints { for _, pt := range branchPoints {
...@@ -1013,21 +591,9 @@ func TestAtan(t *testing.T) { ...@@ -1013,21 +591,9 @@ func TestAtan(t *testing.T) {
t.Errorf("Atan(%g) = %g, want %g", vc[i], f, atan[i]) t.Errorf("Atan(%g) = %g, want %g", vc[i], f, atan[i])
} }
} }
for _, v := range atanSC { for i := 0; i < len(vcAtanSC); i++ {
if f := Atan(v.in); !cAlike(v.want, f) { if f := Atan(vcAtanSC[i]); !cAlike(atanSC[i], f) {
t.Errorf("Atan(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Atan(%g) = %g, want %g", vcAtanSC[i], f, atanSC[i])
}
if cAlike(-v.in, Conj(v.in)) && !cAlike(-v.want, Conj(v.want)) {
// The following conditions can't simultaneously be satisfied for this input.
continue
}
// Atan(Conj(z)) == Conj(Atan(z))
if f := Atan(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Atan(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
}
// Atan(-z) == -Atan(z)
if f := Atan(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) {
t.Errorf("Atan(%g) = %g, want %g", -v.in, f, -v.want)
} }
} }
for _, pt := range branchPoints { for _, pt := range branchPoints {
...@@ -1042,21 +608,9 @@ func TestAtanh(t *testing.T) { ...@@ -1042,21 +608,9 @@ func TestAtanh(t *testing.T) {
t.Errorf("Atanh(%g) = %g, want %g", vc[i], f, atanh[i]) t.Errorf("Atanh(%g) = %g, want %g", vc[i], f, atanh[i])
} }
} }
for _, v := range atanhSC { for i := 0; i < len(vcAtanhSC); i++ {
if f := Atanh(v.in); !cAlike(v.want, f) { if f := Atanh(vcAtanhSC[i]); !cAlike(atanhSC[i], f) {
t.Errorf("Atanh(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Atanh(%g) = %g, want %g", vcAtanhSC[i], f, atanhSC[i])
}
if cAlike(-v.in, Conj(v.in)) && !cAlike(-v.want, Conj(v.want)) {
// The following conditions can't simultaneously be satisfied for this input.
continue
}
// Atanh(Conj(z)) == Conj(Atanh(z))
if f := Atanh(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Atanh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
}
// Atanh(-z) == -Atanh(z)
if f := Atanh(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) {
t.Errorf("Atanh(%g) = %g, want %g", -v.in, f, -v.want)
} }
} }
for _, pt := range branchPoints { for _, pt := range branchPoints {
...@@ -1083,21 +637,9 @@ func TestCos(t *testing.T) { ...@@ -1083,21 +637,9 @@ func TestCos(t *testing.T) {
t.Errorf("Cos(%g) = %g, want %g", vc[i], f, cos[i]) t.Errorf("Cos(%g) = %g, want %g", vc[i], f, cos[i])
} }
} }
for _, v := range cosSC { for i := 0; i < len(vcCosSC); i++ {
if f := Cos(v.in); !cAlike(v.want, f) { if f := Cos(vcCosSC[i]); !cAlike(cosSC[i], f) {
t.Errorf("Cos(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Cos(%g) = %g, want %g", vcCosSC[i], f, cosSC[i])
}
if cAlike(-v.in, Conj(v.in)) && !cAlike(v.want, Conj(v.want)) {
// The following conditions can't simultaneously be satisfied for this input.
continue
}
// Cos(Conj(z)) == Cos(Cosh(z))
if f := Cos(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Cos(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
}
// Cos(-z) == Cos(z)
if f := Cos(-v.in); !cAlike(v.want, f) && !cAlike(v.in, -v.in) {
t.Errorf("Cos(%g) = %g, want %g", -v.in, f, v.want)
} }
} }
} }
...@@ -1107,21 +649,9 @@ func TestCosh(t *testing.T) { ...@@ -1107,21 +649,9 @@ func TestCosh(t *testing.T) {
t.Errorf("Cosh(%g) = %g, want %g", vc[i], f, cosh[i]) t.Errorf("Cosh(%g) = %g, want %g", vc[i], f, cosh[i])
} }
} }
for _, v := range coshSC { for i := 0; i < len(vcCoshSC); i++ {
if f := Cosh(v.in); !cAlike(v.want, f) { if f := Cosh(vcCoshSC[i]); !cAlike(coshSC[i], f) {
t.Errorf("Cosh(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Cosh(%g) = %g, want %g", vcCoshSC[i], f, coshSC[i])
}
if cAlike(-v.in, Conj(v.in)) && !cAlike(v.want, Conj(v.want)) {
// The following conditions can't simultaneously be satisfied for this input.
continue
}
// Cosh(Conj(z)) == Conj(Cosh(z))
if f := Cosh(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Cosh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
}
// Cosh(-z) == Cosh(z)
if f := Cosh(-v.in); !cAlike(v.want, f) && !cAlike(v.in, -v.in) {
t.Errorf("Cosh(%g) = %g, want %g", -v.in, f, v.want)
} }
} }
} }
...@@ -1131,13 +661,9 @@ func TestExp(t *testing.T) { ...@@ -1131,13 +661,9 @@ func TestExp(t *testing.T) {
t.Errorf("Exp(%g) = %g, want %g", vc[i], f, exp[i]) t.Errorf("Exp(%g) = %g, want %g", vc[i], f, exp[i])
} }
} }
for _, v := range expSC { for i := 0; i < len(vcExpSC); i++ {
if f := Exp(v.in); !cAlike(v.want, f) { if f := Exp(vcExpSC[i]); !cAlike(expSC[i], f) {
t.Errorf("Exp(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Exp(%g) = %g, want %g", vcExpSC[i], f, expSC[i])
}
// Exp(Conj(z)) == Exp(Cosh(z))
if f := Exp(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Exp(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
} }
} }
} }
...@@ -1154,13 +680,9 @@ func TestLog(t *testing.T) { ...@@ -1154,13 +680,9 @@ func TestLog(t *testing.T) {
t.Errorf("Log(%g) = %g, want %g", vc[i], f, log[i]) t.Errorf("Log(%g) = %g, want %g", vc[i], f, log[i])
} }
} }
for _, v := range logSC { for i := 0; i < len(vcLogSC); i++ {
if f := Log(v.in); !cAlike(v.want, f) { if f := Log(vcLogSC[i]); !cAlike(logSC[i], f) {
t.Errorf("Log(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Log(%g) = %g, want %g", vcLogSC[i], f, logSC[i])
}
// Log(Conj(z)) == Conj(Log(z))
if f := Log(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Log(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
} }
} }
for _, pt := range branchPoints { for _, pt := range branchPoints {
...@@ -1175,13 +697,9 @@ func TestLog10(t *testing.T) { ...@@ -1175,13 +697,9 @@ func TestLog10(t *testing.T) {
t.Errorf("Log10(%g) = %g, want %g", vc[i], f, log10[i]) t.Errorf("Log10(%g) = %g, want %g", vc[i], f, log10[i])
} }
} }
for _, v := range log10SC { for i := 0; i < len(vcLog10SC); i++ {
if f := Log10(v.in); !cAlike(v.want, f) { if f := Log10(vcLog10SC[i]); !cAlike(log10SC[i], f) {
t.Errorf("Log10(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Log10(%g) = %g, want %g", vcLog10SC[i], f, log10SC[i])
}
// Log10(Conj(z)) == Conj(Log10(z))
if f := Log10(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Log10(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
} }
} }
} }
...@@ -1246,22 +764,9 @@ func TestSin(t *testing.T) { ...@@ -1246,22 +764,9 @@ func TestSin(t *testing.T) {
t.Errorf("Sin(%g) = %g, want %g", vc[i], f, sin[i]) t.Errorf("Sin(%g) = %g, want %g", vc[i], f, sin[i])
} }
} }
for _, v := range sinSC { for i := 0; i < len(vcSinSC); i++ {
if f := Sin(v.in); !cAlike(v.want, f) { if f := Sin(vcSinSC[i]); !cAlike(sinSC[i], f) {
t.Errorf("Sin(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Sin(%g) = %g, want %g", vcSinSC[i], f, sinSC[i])
}
if cAlike(-v.in, Conj(v.in)) && !cAlike(-v.want, Conj(v.want)) {
// The following conditions can't simultaneously be satisfied for this input.
continue
}
// Sin(Conj(z)) == Conj(Sin(z))
if f := Sin(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Sinh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
}
// Sin(-z) == -Sin(z)
if f := Sin(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) {
t.Errorf("Sinh(%g) = %g, want %g", -v.in, f, -v.want)
} }
} }
} }
...@@ -1271,21 +776,9 @@ func TestSinh(t *testing.T) { ...@@ -1271,21 +776,9 @@ func TestSinh(t *testing.T) {
t.Errorf("Sinh(%g) = %g, want %g", vc[i], f, sinh[i]) t.Errorf("Sinh(%g) = %g, want %g", vc[i], f, sinh[i])
} }
} }
for _, v := range sinhSC { for i := 0; i < len(vcSinhSC); i++ {
if f := Sinh(v.in); !cAlike(v.want, f) { if f := Sinh(vcSinhSC[i]); !cAlike(sinhSC[i], f) {
t.Errorf("Sinh(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Sinh(%g) = %g, want %g", vcSinhSC[i], f, sinhSC[i])
}
if cAlike(-v.in, Conj(v.in)) && !cAlike(-v.want, Conj(v.want)) {
// The following conditions can't simultaneously be satisfied for this input.
continue
}
// Sinh(Conj(z)) == Conj(Sinh(z))
if f := Sinh(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Sinh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
}
// Sinh(-z) == -Sinh(z)
if f := Sinh(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) {
t.Errorf("Sinh(%g) = %g, want %g", -v.in, f, -v.want)
} }
} }
} }
...@@ -1295,13 +788,9 @@ func TestSqrt(t *testing.T) { ...@@ -1295,13 +788,9 @@ func TestSqrt(t *testing.T) {
t.Errorf("Sqrt(%g) = %g, want %g", vc[i], f, sqrt[i]) t.Errorf("Sqrt(%g) = %g, want %g", vc[i], f, sqrt[i])
} }
} }
for _, v := range sqrtSC { for i := 0; i < len(vcSqrtSC); i++ {
if f := Sqrt(v.in); !cAlike(v.want, f) { if f := Sqrt(vcSqrtSC[i]); !cAlike(sqrtSC[i], f) {
t.Errorf("Sqrt(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Sqrt(%g) = %g, want %g", vcSqrtSC[i], f, sqrtSC[i])
}
// Sqrt(Conj(z)) == Conj(Sqrt(z))
if f := Sqrt(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Sqrt(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
} }
} }
for _, pt := range branchPoints { for _, pt := range branchPoints {
...@@ -1316,21 +805,9 @@ func TestTan(t *testing.T) { ...@@ -1316,21 +805,9 @@ func TestTan(t *testing.T) {
t.Errorf("Tan(%g) = %g, want %g", vc[i], f, tan[i]) t.Errorf("Tan(%g) = %g, want %g", vc[i], f, tan[i])
} }
} }
for _, v := range tanSC { for i := 0; i < len(vcTanSC); i++ {
if f := Tan(v.in); !cAlike(v.want, f) { if f := Tan(vcTanSC[i]); !cAlike(tanSC[i], f) {
t.Errorf("Tan(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Tan(%g) = %g, want %g", vcTanSC[i], f, tanSC[i])
}
if cAlike(-v.in, Conj(v.in)) && !cAlike(-v.want, Conj(v.want)) {
// The following conditions can't simultaneously be satisfied for this input.
continue
}
// Tan(Conj(z)) == Conj(Tan(z))
if f := Tan(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Tan(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
}
// Tan(-z) == -Tan(z)
if f := Tan(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) {
t.Errorf("Tan(%g) = %g, want %g", -v.in, f, -v.want)
} }
} }
} }
...@@ -1340,21 +817,9 @@ func TestTanh(t *testing.T) { ...@@ -1340,21 +817,9 @@ func TestTanh(t *testing.T) {
t.Errorf("Tanh(%g) = %g, want %g", vc[i], f, tanh[i]) t.Errorf("Tanh(%g) = %g, want %g", vc[i], f, tanh[i])
} }
} }
for _, v := range tanhSC { for i := 0; i < len(vcTanhSC); i++ {
if f := Tanh(v.in); !cAlike(v.want, f) { if f := Tanh(vcTanhSC[i]); !cAlike(tanhSC[i], f) {
t.Errorf("Tanh(%g) = %g, want %g", v.in, f, v.want) t.Errorf("Tanh(%g) = %g, want %g", vcTanhSC[i], f, tanhSC[i])
}
if cAlike(-v.in, Conj(v.in)) && !cAlike(-v.want, Conj(v.want)) {
// The following conditions can't simultaneously be satisfied for this input.
continue
}
// Tanh(Conj(z)) == Conj(Tanh(z))
if f := Tanh(Conj(v.in)); !cAlike(Conj(v.want), f) && !cAlike(v.in, Conj(v.in)) {
t.Errorf("Tanh(%g) = %g, want %g", Conj(v.in), f, Conj(v.want))
}
// Tanh(-z) == -Tanh(z)
if f := Tanh(-v.in); !cAlike(-v.want, f) && !cAlike(v.in, -v.in) {
t.Errorf("Tanh(%g) = %g, want %g", -v.in, f, -v.want)
} }
} }
} }
......
...@@ -49,23 +49,6 @@ import "math" ...@@ -49,23 +49,6 @@ import "math"
// Exp returns e**x, the base-e exponential of x. // Exp returns e**x, the base-e exponential of x.
func Exp(x complex128) complex128 { func Exp(x complex128) complex128 {
switch re, im := real(x), imag(x); {
case math.IsInf(re, 0):
switch {
case re > 0 && im == 0:
return x
case math.IsInf(im, 0) || math.IsNaN(im):
if re < 0 {
return complex(0, math.Copysign(0, im))
} else {
return complex(math.Inf(1.0), math.NaN())
}
}
case math.IsNaN(re):
if im == 0 {
return complex(math.NaN(), im)
}
}
r := math.Exp(real(x)) r := math.Exp(real(x))
s, c := math.Sincos(imag(x)) s, c := math.Sincos(imag(x))
return complex(r*c, r*s) return complex(r*c, r*s)
......
...@@ -60,6 +60,5 @@ func Log(x complex128) complex128 { ...@@ -60,6 +60,5 @@ func Log(x complex128) complex128 {
// Log10 returns the decimal logarithm of x. // Log10 returns the decimal logarithm of x.
func Log10(x complex128) complex128 { func Log10(x complex128) complex128 {
z := Log(x) return math.Log10E * Log(x)
return complex(math.Log10E*real(z), math.Log10E*imag(z))
} }
...@@ -51,19 +51,6 @@ import "math" ...@@ -51,19 +51,6 @@ import "math"
// Sin returns the sine of x. // Sin returns the sine of x.
func Sin(x complex128) complex128 { func Sin(x complex128) complex128 {
switch re, im := real(x), imag(x); {
case im == 0 && (math.IsInf(re, 0) || math.IsNaN(re)):
return complex(math.NaN(), im)
case math.IsInf(im, 0):
switch {
case re == 0:
return x
case math.IsInf(re, 0) || math.IsNaN(re):
return complex(math.NaN(), im)
}
case re == 0 && math.IsNaN(im):
return x
}
s, c := math.Sincos(real(x)) s, c := math.Sincos(real(x))
sh, ch := sinhcosh(imag(x)) sh, ch := sinhcosh(imag(x))
return complex(s*ch, c*sh) return complex(s*ch, c*sh)
...@@ -84,19 +71,6 @@ func Sin(x complex128) complex128 { ...@@ -84,19 +71,6 @@ func Sin(x complex128) complex128 {
// Sinh returns the hyperbolic sine of x. // Sinh returns the hyperbolic sine of x.
func Sinh(x complex128) complex128 { func Sinh(x complex128) complex128 {
switch re, im := real(x), imag(x); {
case re == 0 && (math.IsInf(im, 0) || math.IsNaN(im)):
return complex(re, math.NaN())
case math.IsInf(re, 0):
switch {
case im == 0:
return complex(re, im)
case math.IsInf(im, 0) || math.IsNaN(im):
return complex(re, math.NaN())
}
case im == 0 && math.IsNaN(re):
return complex(math.NaN(), im)
}
s, c := math.Sincos(imag(x)) s, c := math.Sincos(imag(x))
sh, ch := sinhcosh(real(x)) sh, ch := sinhcosh(real(x))
return complex(c*sh, s*ch) return complex(c*sh, s*ch)
...@@ -122,19 +96,6 @@ func Sinh(x complex128) complex128 { ...@@ -122,19 +96,6 @@ func Sinh(x complex128) complex128 {
// Cos returns the cosine of x. // Cos returns the cosine of x.
func Cos(x complex128) complex128 { func Cos(x complex128) complex128 {
switch re, im := real(x), imag(x); {
case im == 0 && (math.IsInf(re, 0) || math.IsNaN(re)):
return complex(math.NaN(), -im*math.Copysign(0, re))
case math.IsInf(im, 0):
switch {
case re == 0:
return complex(math.Inf(1), -re*math.Copysign(0, im))
case math.IsInf(re, 0) || math.IsNaN(re):
return complex(math.Inf(1), math.NaN())
}
case re == 0 && math.IsNaN(im):
return complex(math.NaN(), 0)
}
s, c := math.Sincos(real(x)) s, c := math.Sincos(real(x))
sh, ch := sinhcosh(imag(x)) sh, ch := sinhcosh(imag(x))
return complex(c*ch, -s*sh) return complex(c*ch, -s*sh)
...@@ -154,19 +115,6 @@ func Cos(x complex128) complex128 { ...@@ -154,19 +115,6 @@ func Cos(x complex128) complex128 {
// Cosh returns the hyperbolic cosine of x. // Cosh returns the hyperbolic cosine of x.
func Cosh(x complex128) complex128 { func Cosh(x complex128) complex128 {
switch re, im := real(x), imag(x); {
case re == 0 && (math.IsInf(im, 0) || math.IsNaN(im)):
return complex(math.NaN(), re*math.Copysign(0, im))
case math.IsInf(re, 0):
switch {
case im == 0:
return complex(math.Inf(1), im*math.Copysign(0, re))
case math.IsInf(im, 0) || math.IsNaN(im):
return complex(math.Inf(1), math.NaN())
}
case im == 0 && math.IsNaN(re):
return complex(math.NaN(), im)
}
s, c := math.Sincos(imag(x)) s, c := math.Sincos(imag(x))
sh, ch := sinhcosh(real(x)) sh, ch := sinhcosh(real(x))
return complex(c*ch, s*sh) return complex(c*ch, s*sh)
......
...@@ -65,8 +65,6 @@ func Sqrt(x complex128) complex128 { ...@@ -65,8 +65,6 @@ func Sqrt(x complex128) complex128 {
return complex(0, math.Copysign(math.Sqrt(-real(x)), imag(x))) return complex(0, math.Copysign(math.Sqrt(-real(x)), imag(x)))
} }
return complex(math.Sqrt(real(x)), imag(x)) return complex(math.Sqrt(real(x)), imag(x))
} else if math.IsInf(imag(x), 0) {
return complex(math.Inf(1.0), imag(x))
} }
if real(x) == 0 { if real(x) == 0 {
if imag(x) < 0 { if imag(x) < 0 {
......
...@@ -57,16 +57,6 @@ import "math" ...@@ -57,16 +57,6 @@ import "math"
// Tan returns the tangent of x. // Tan returns the tangent of x.
func Tan(x complex128) complex128 { func Tan(x complex128) complex128 {
switch re, im := real(x), imag(x); {
case math.IsInf(im, 0):
switch {
case math.IsInf(re, 0) || math.IsNaN(re):
return complex(math.Copysign(0, re), math.Copysign(1, im))
}
return complex(math.Copysign(0, math.Sin(2*re)), math.Copysign(1, im))
case re == 0 && math.IsNaN(im):
return x
}
d := math.Cos(2*real(x)) + math.Cosh(2*imag(x)) d := math.Cos(2*real(x)) + math.Cosh(2*imag(x))
if math.Abs(d) < 0.25 { if math.Abs(d) < 0.25 {
d = tanSeries(x) d = tanSeries(x)
...@@ -91,16 +81,6 @@ func Tan(x complex128) complex128 { ...@@ -91,16 +81,6 @@ func Tan(x complex128) complex128 {
// Tanh returns the hyperbolic tangent of x. // Tanh returns the hyperbolic tangent of x.
func Tanh(x complex128) complex128 { func Tanh(x complex128) complex128 {
switch re, im := real(x), imag(x); {
case math.IsInf(re, 0):
switch {
case math.IsInf(im, 0) || math.IsNaN(im):
return complex(math.Copysign(1, re), math.Copysign(0, im))
}
return complex(math.Copysign(1, re), math.Copysign(0, math.Sin(2*im)))
case im == 0 && math.IsNaN(re):
return x
}
d := math.Cosh(2*real(x)) + math.Cos(2*imag(x)) d := math.Cosh(2*real(x)) + math.Cos(2*imag(x))
if d == 0 { if d == 0 {
return Inf() return Inf()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment