]> Cypherpunks repositories - gostls13.git/commitdiff
math: special cases for Fmod
authorCharles L. Dorian <cldorian@gmail.com>
Tue, 12 Jan 2010 00:20:51 +0000 (16:20 -0800)
committerRuss Cox <rsc@golang.org>
Tue, 12 Jan 2010 00:20:51 +0000 (16:20 -0800)
Added special case tests to all_test.go for Fmod. Fixed Fmod [hung
for Fmod(+/-Inf, <finite>)]. Also added test for Ceil in all_test.go.

R=rsc
CC=golang-dev
https://golang.org/cl/186076

src/pkg/math/all_test.go
src/pkg/math/fmod.go

index 7dcc41f41b59d0d6794b77493a1314e3c9a3934a..9f3948989f21e9961655b9fdf8712c539e8f65c0 100644 (file)
@@ -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
 // license that can be found in the LICENSE file.
 
@@ -58,6 +58,18 @@ var atan = []float64{
        1.0696031952318783e+00,
        -1.4561721938838085e+00,
 }
+var ceil = []float64{
+       5.0000000000000000e+00,
+       8.0000000000000000e+00,
+       0.0000000000000000e+00,
+       -5.0000000000000000e+00,
+       1.0000000000000000e+01,
+       3.0000000000000000e+00,
+       6.0000000000000000e+00,
+       3.0000000000000000e+00,
+       2.0000000000000000e+00,
+       -8.0000000000000000e+00,
+}
 var exp = []float64{
        1.4533071302642137e+02,
        2.2958822575694450e+03,
@@ -82,6 +94,18 @@ var floor = []float64{
        1.0000000000000000e+00,
        -9.0000000000000000e+00,
 }
+var fmod = []float64{
+       4.1976150232653000e-02,
+       2.2611275254218955e+00,
+       3.2317941087942760e-02,
+       4.9893963817289251e+00,
+       3.6370629280158270e-01,
+       1.2208682822681062e+00,
+       4.7709165685406934e+00,
+       1.8161802686919694e+00,
+       8.7345954159572500e-01,
+       1.3140752314243987e+00,
+}
 var log = []float64{
        1.6052314626930630e+00,
        2.0462560018708768e+00,
@@ -185,6 +209,72 @@ var vfatanSC = []float64{
 var atanSC = []float64{
        NaN(),
 }
+
+var vffmodSC = [][2]float64{
+       [2]float64{Inf(-1), Inf(-1)},
+       [2]float64{Inf(-1), -Pi},
+       [2]float64{Inf(-1), 0},
+       [2]float64{Inf(-1), Pi},
+       [2]float64{Inf(-1), Inf(1)},
+       [2]float64{Inf(-1), NaN()},
+       [2]float64{-Pi, Inf(-1)},
+       [2]float64{-Pi, 0},
+       [2]float64{-Pi, Inf(1)},
+       [2]float64{-Pi, NaN()},
+       [2]float64{0, Inf(-1)},
+       [2]float64{0, 0},
+       [2]float64{0, Inf(1)},
+       [2]float64{0, NaN()},
+       [2]float64{Pi, Inf(-1)},
+       [2]float64{Pi, 0},
+       [2]float64{Pi, Inf(1)},
+       [2]float64{Pi, NaN()},
+       [2]float64{Inf(1), Inf(-1)},
+       [2]float64{Inf(1), -Pi},
+       [2]float64{Inf(1), 0},
+       [2]float64{Inf(1), Pi},
+       [2]float64{Inf(1), Inf(1)},
+       [2]float64{Inf(1), NaN()},
+       [2]float64{NaN(), Inf(-1)},
+       [2]float64{NaN(), -Pi},
+       [2]float64{NaN(), 0},
+       [2]float64{NaN(), Pi},
+       [2]float64{NaN(), Inf(1)},
+       [2]float64{NaN(), NaN()},
+}
+var fmodSC = []float64{
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+       -Pi,
+       NaN(),
+       -Pi,
+       NaN(),
+       0,
+       NaN(),
+       0,
+       NaN(),
+       Pi,
+       NaN(),
+       Pi,
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+       NaN(),
+}
+
 var vfpowSC = [][2]float64{
        [2]float64{-Pi, Pi},
        [2]float64{-Pi, -Pi},
@@ -344,6 +434,14 @@ func TestAtan(t *testing.T) {
        }
 }
 
+func TestCeil(t *testing.T) {
+       for i := 0; i < len(vf); i++ {
+               if f := Ceil(vf[i]); ceil[i] != f {
+                       t.Errorf("Ceil(%g) = %g, want %g\n", vf[i], f, ceil[i])
+               }
+       }
+}
+
 func TestExp(t *testing.T) {
        for i := 0; i < len(vf); i++ {
                if f := Exp(vf[i]); !veryclose(exp[i], f) {
@@ -360,6 +458,19 @@ func TestFloor(t *testing.T) {
        }
 }
 
+func TestFmod(t *testing.T) {
+       for i := 0; i < len(vf); i++ {
+               if f := Fmod(10, vf[i]); !close(fmod[i], f) {
+                       t.Errorf("Fmod(10, %.17g) = %.17g, want %.17g\n", vf[i], f, fmod[i])
+               }
+       }
+       for i := 0; i < len(vffmodSC); i++ {
+               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])
+               }
+       }
+}
+
 func TestLog(t *testing.T) {
        for i := 0; i < len(vf); i++ {
                a := Fabs(vf[i])
index cff9ae497b191acb055be1f9fc8d578728336be2..fc57f7483fa57352702a8b9911e4871057b8c93d 100644 (file)
@@ -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
 // license that can be found in the LICENSE file.
 
@@ -6,13 +6,21 @@ package math
 
 
 /*
-       Floating-point mod func without infinity or NaN checking
+       Floating-point mod function.
 */
 
 // Fmod returns the floating-point remainder of x/y.
+// The magnitude of the result is less than y and its
+// sign agrees with that of x.
+//
+// Special cases are:
+//     if x is not finite, Fmod returns NaN
+//     if y is 0 or NaN, Fmod returns NaN
 func Fmod(x, y float64) float64 {
-       if y == 0 {
-               return x
+       // TODO(rsc): Remove manual inlining of IsNaN, IsInf
+       // when compiler does it for us.
+       if y == 0 || x > MaxFloat64 || x < -MaxFloat64 || x != x || y != y { // y == 0 || IsInf(x, 0) || IsNaN(x) || IsNan(y)
+               return NaN()
        }
        if y < 0 {
                y = -y