mirror of
https://github.com/golang/go
synced 2024-11-22 12:04:46 -07:00
math: special cases for Hypot
Added special case tests to all_test.go. Added tests to hypot.go, otherwise hangs. R=rsc CC=golang-dev https://golang.org/cl/186118
This commit is contained in:
parent
7f11db5ea9
commit
9a6b8e21e4
@ -309,6 +309,41 @@ var fmodSC = []float64{
|
|||||||
NaN(),
|
NaN(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var vfhypotSC = [][2]float64{
|
||||||
|
[2]float64{Inf(-1), Inf(-1)},
|
||||||
|
[2]float64{Inf(-1), 0},
|
||||||
|
[2]float64{Inf(-1), Inf(1)},
|
||||||
|
[2]float64{Inf(-1), NaN()},
|
||||||
|
[2]float64{0, Inf(-1)},
|
||||||
|
[2]float64{0, Inf(1)},
|
||||||
|
[2]float64{0, NaN()},
|
||||||
|
[2]float64{Inf(1), Inf(-1)},
|
||||||
|
[2]float64{Inf(1), 0},
|
||||||
|
[2]float64{Inf(1), Inf(1)},
|
||||||
|
[2]float64{Inf(1), NaN()},
|
||||||
|
[2]float64{NaN(), Inf(-1)},
|
||||||
|
[2]float64{NaN(), 0},
|
||||||
|
[2]float64{NaN(), Inf(1)},
|
||||||
|
[2]float64{NaN(), NaN()},
|
||||||
|
}
|
||||||
|
var hypotSC = []float64{
|
||||||
|
Inf(1),
|
||||||
|
Inf(1),
|
||||||
|
Inf(1),
|
||||||
|
Inf(1),
|
||||||
|
Inf(1),
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
Inf(1),
|
||||||
|
Inf(1),
|
||||||
|
Inf(1),
|
||||||
|
Inf(1),
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
}
|
||||||
|
|
||||||
var vflogSC = []float64{
|
var vflogSC = []float64{
|
||||||
Inf(-1),
|
Inf(-1),
|
||||||
-Pi,
|
-Pi,
|
||||||
@ -413,6 +448,19 @@ var powSC = []float64{
|
|||||||
1,
|
1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var vfsqrtSC = []float64{
|
||||||
|
Inf(-1),
|
||||||
|
-Pi,
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
}
|
||||||
|
var sqrtSC = []float64{
|
||||||
|
NaN(),
|
||||||
|
NaN(),
|
||||||
|
Inf(1),
|
||||||
|
NaN(),
|
||||||
|
}
|
||||||
|
|
||||||
func tolerance(a, b, e float64) bool {
|
func tolerance(a, b, e float64) bool {
|
||||||
d := a - b
|
d := a - b
|
||||||
if d < 0 {
|
if d < 0 {
|
||||||
@ -525,12 +573,26 @@ func TestFloor(t *testing.T) {
|
|||||||
func TestFmod(t *testing.T) {
|
func TestFmod(t *testing.T) {
|
||||||
for i := 0; i < len(vf); i++ {
|
for i := 0; i < len(vf); i++ {
|
||||||
if f := Fmod(10, vf[i]); !close(fmod[i], f) {
|
if f := Fmod(10, vf[i]); !close(fmod[i], f) {
|
||||||
t.Errorf("Fmod(10, %.17g) = %.17g, want %.17g\n", vf[i], f, fmod[i])
|
t.Errorf("Fmod(10, %g) = %g, want %g\n", vf[i], f, fmod[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := 0; i < len(vffmodSC); i++ {
|
for i := 0; i < len(vffmodSC); i++ {
|
||||||
if f := Fmod(vffmodSC[i][0], vffmodSC[i][1]); !alike(fmodSC[i], f) {
|
if f := Fmod(vffmodSC[i][0], vffmodSC[i][1]); !alike(fmodSC[i], f) {
|
||||||
t.Errorf("Fmod(%.17g, %.17g) = %.17g, want %.17g\n", vffmodSC[i][0], vffmodSC[i][1], f, fmodSC[i])
|
t.Errorf("Fmod(%g, %g) = %g, want %g\n", vffmodSC[i][0], vffmodSC[i][1], f, fmodSC[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHypot(t *testing.T) {
|
||||||
|
for i := 0; i < len(vf); i++ {
|
||||||
|
a := Fabs(tanh[i] * Sqrt(2))
|
||||||
|
if f := Hypot(tanh[i], tanh[i]); a != f {
|
||||||
|
t.Errorf("Hypot(%g, %g) = %g, want %g\n", tanh[i], tanh[i], f, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 0; i < len(vfhypotSC); i++ {
|
||||||
|
if f := Hypot(vfhypotSC[i][0], vfhypotSC[i][1]); !alike(hypotSC[i], f) {
|
||||||
|
t.Errorf("Hypot(%g, %g) = %g, want %g\n", vfhypotSC[i][0], vfhypotSC[i][1], f, hypotSC[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -572,12 +634,12 @@ func TestLog10(t *testing.T) {
|
|||||||
func TestPow(t *testing.T) {
|
func TestPow(t *testing.T) {
|
||||||
for i := 0; i < len(vf); i++ {
|
for i := 0; i < len(vf); i++ {
|
||||||
if f := Pow(10, vf[i]); !close(pow[i], f) {
|
if f := Pow(10, vf[i]); !close(pow[i], f) {
|
||||||
t.Errorf("Pow(10, %.17g) = %.17g, want %.17g\n", vf[i], f, pow[i])
|
t.Errorf("Pow(10, %g) = %g, want %g\n", vf[i], f, pow[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := 0; i < len(vfpowSC); i++ {
|
for i := 0; i < len(vfpowSC); i++ {
|
||||||
if f := Pow(vfpowSC[i][0], vfpowSC[i][1]); !alike(powSC[i], f) {
|
if f := Pow(vfpowSC[i][0], vfpowSC[i][1]); !alike(powSC[i], f) {
|
||||||
t.Errorf("Pow(%.17g, %.17g) = %.17g, want %.17g\n", vfpowSC[i][0], vfpowSC[i][1], f, powSC[i])
|
t.Errorf("Pow(%g, %g) = %g, want %g\n", vfpowSC[i][0], vfpowSC[i][1], f, powSC[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -609,6 +671,11 @@ func TestSqrt(t *testing.T) {
|
|||||||
t.Errorf("Sqrt(%g) = %g, want %g\n", a, f, sqrt[i])
|
t.Errorf("Sqrt(%g) = %g, want %g\n", a, f, sqrt[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for i := 0; i < len(vfsqrtSC); i++ {
|
||||||
|
if f := Log10(vfsqrtSC[i]); !alike(sqrtSC[i], f) {
|
||||||
|
t.Errorf("Sqrt(%g) = %g, want %g\n", vfsqrtSC[i], f, sqrtSC[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTan(t *testing.T) {
|
func TestTan(t *testing.T) {
|
||||||
@ -627,15 +694,6 @@ func TestTanh(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHypot(t *testing.T) {
|
|
||||||
for i := 0; i < len(vf); i++ {
|
|
||||||
a := Fabs(tanh[i] * Sqrt(2))
|
|
||||||
if f := Hypot(tanh[i], tanh[i]); a != f {
|
|
||||||
t.Errorf("Hypot(%g, %g) = %g, want %g\n", tanh[i], tanh[i], f, a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that math functions of high angle values
|
// Check that math functions of high angle values
|
||||||
// return similar results to low angle values
|
// return similar results to low angle values
|
||||||
func TestLargeSin(t *testing.T) {
|
func TestLargeSin(t *testing.T) {
|
||||||
@ -700,18 +758,6 @@ func TestFloatMinMax(t *testing.T) {
|
|||||||
|
|
||||||
// Benchmarks
|
// Benchmarks
|
||||||
|
|
||||||
func BenchmarkPowInt(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
Pow(2, 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkPowFrac(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
Pow(2.5, 1.5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkAtan(b *testing.B) {
|
func BenchmarkAtan(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
Atan(.5)
|
Atan(.5)
|
||||||
@ -730,6 +776,18 @@ func BenchmarkAcos(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkPowInt(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
Pow(2, 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkPowFrac(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
Pow(2.5, 1.5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkSqrt(b *testing.B) {
|
func BenchmarkSqrt(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
Sqrt(10)
|
Sqrt(10)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2009 The Go Authors. All rights reserved.
|
// Copyright 2009-2010 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
@ -15,7 +15,20 @@ package math
|
|||||||
|
|
||||||
// Hypot computes Sqrt(p*p + q*q), taking care to avoid
|
// Hypot computes Sqrt(p*p + q*q), taking care to avoid
|
||||||
// unnecessary overflow and underflow.
|
// unnecessary overflow and underflow.
|
||||||
|
//
|
||||||
|
// Special cases are:
|
||||||
|
// Hypot(p, q) = +Inf if p or q is infinite
|
||||||
|
// Hypot(p, q) = NaN if p or q is NaN
|
||||||
func Hypot(p, q float64) float64 {
|
func Hypot(p, q float64) float64 {
|
||||||
|
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
|
||||||
|
// when compiler does it for us
|
||||||
|
// special cases
|
||||||
|
switch {
|
||||||
|
case p < -MaxFloat64 || p > MaxFloat64 || q < -MaxFloat64 || q > MaxFloat64: // IsInf(p, 0) || IsInf(q, 0):
|
||||||
|
return Inf(1)
|
||||||
|
case p != p || q != q: // IsNaN(p) || IsNaN(q):
|
||||||
|
return NaN()
|
||||||
|
}
|
||||||
if p < 0 {
|
if p < 0 {
|
||||||
p = -p
|
p = -p
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user