]> Cypherpunks repositories - gostls13.git/commitdiff
math: implement Nextafter32
authorRobert Griesemer <gri@golang.org>
Wed, 11 Jun 2014 16:09:37 +0000 (09:09 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 11 Jun 2014 16:09:37 +0000 (09:09 -0700)
Provide Nextafter64 as alias to Nextafter.
For submission after the 1.3 release.

Fixes #8117.

LGTM=adonovan
R=adonovan
CC=golang-codereviews
https://golang.org/cl/101750048

src/pkg/math/all_test.go
src/pkg/math/nextafter.go

index 0d8b10f67fa0125aec765ae1378a610d67106cd5..8b00ef1d6c5b07ac27dea2e279ac90c34231c2a1 100644 (file)
@@ -456,7 +456,19 @@ var modf = [][2]float64{
        {1.0000000000000000e+00, 8.2530809168085506044576505e-01},
        {-8.0000000000000000e+00, -6.8592476857560136238589621e-01},
 }
-var nextafter = []float64{
+var nextafter32 = []float32{
+       4.979012489318848e+00,
+       7.738873004913330e+00,
+       -2.768800258636475e-01,
+       -5.010602951049805e+00,
+       9.636294364929199e+00,
+       2.926377534866333e+00,
+       5.229084014892578e+00,
+       2.727940082550049e+00,
+       1.825308203697205e+00,
+       -8.685923576354980e+00,
+}
+var nextafter64 = []float64{
        4.97901192488367438926388786e+00,
        7.73887247457810545370193722e+00,
        -2.7688005719200153853520874e-01,
@@ -1331,7 +1343,32 @@ var modfSC = [][2]float64{
        {NaN(), NaN()},
 }
 
-var vfnextafterSC = [][2]float64{
+var vfnextafter32SC = [][2]float32{
+       {0, 0},
+       {0, float32(Copysign(0, -1))},
+       {0, -1},
+       {0, float32(NaN())},
+       {float32(Copysign(0, -1)), 1},
+       {float32(Copysign(0, -1)), 0},
+       {float32(Copysign(0, -1)), float32(Copysign(0, -1))},
+       {float32(Copysign(0, -1)), -1},
+       {float32(NaN()), 0},
+       {float32(NaN()), float32(NaN())},
+}
+var nextafter32SC = []float32{
+       0,
+       0,
+       -1.401298464e-45, // Float32frombits(0x80000001)
+       float32(NaN()),
+       1.401298464e-45, // Float32frombits(0x00000001)
+       float32(Copysign(0, -1)),
+       float32(Copysign(0, -1)),
+       -1.401298464e-45, // Float32frombits(0x80000001)
+       float32(NaN()),
+       float32(NaN()),
+}
+
+var vfnextafter64SC = [][2]float64{
        {0, 0},
        {0, Copysign(0, -1)},
        {0, -1},
@@ -1343,7 +1380,7 @@ var vfnextafterSC = [][2]float64{
        {NaN(), 0},
        {NaN(), NaN()},
 }
-var nextafterSC = []float64{
+var nextafter64SC = []float64{
        0,
        0,
        -4.9406564584124654418e-324, // Float64frombits(0x8000000000000001)
@@ -2303,15 +2340,29 @@ func TestModf(t *testing.T) {
        }
 }
 
-func TestNextafter(t *testing.T) {
+func TestNextafter32(t *testing.T) {
+       for i := 0; i < len(vf); i++ {
+               vfi := float32(vf[i])
+               if f := Nextafter32(vfi, 10); nextafter32[i] != f {
+                       t.Errorf("Nextafter32(%g, %g) = %g want %g", vfi, 10.0, f, nextafter32[i])
+               }
+       }
+       for i := 0; i < len(vfnextafter32SC); i++ {
+               if f := Nextafter32(vfnextafter32SC[i][0], vfnextafter32SC[i][1]); !alike(float64(nextafter32SC[i]), float64(f)) {
+                       t.Errorf("Nextafter32(%g, %g) = %g want %g", vfnextafter32SC[i][0], vfnextafter32SC[i][1], f, nextafter32SC[i])
+               }
+       }
+}
+
+func TestNextafter64(t *testing.T) {
        for i := 0; i < len(vf); i++ {
-               if f := Nextafter(vf[i], 10); nextafter[i] != f {
-                       t.Errorf("Nextafter(%g, %g) = %g want %g", vf[i], 10.0, f, nextafter[i])
+               if f := Nextafter64(vf[i], 10); nextafter64[i] != f {
+                       t.Errorf("Nextafter64(%g, %g) = %g want %g", vf[i], 10.0, f, nextafter64[i])
                }
        }
-       for i := 0; i < len(vfnextafterSC); i++ {
-               if f := Nextafter(vfnextafterSC[i][0], vfnextafterSC[i][1]); !alike(nextafterSC[i], f) {
-                       t.Errorf("Nextafter(%g, %g) = %g want %g", vfnextafterSC[i][0], vfnextafterSC[i][1], f, nextafterSC[i])
+       for i := 0; i < len(vfnextafter64SC); i++ {
+               if f := Nextafter64(vfnextafter64SC[i][0], vfnextafter64SC[i][1]); !alike(nextafter64SC[i], f) {
+                       t.Errorf("Nextafter64(%g, %g) = %g want %g", vfnextafter64SC[i][0], vfnextafter64SC[i][1], f, nextafter64SC[i])
                }
        }
 }
@@ -2827,9 +2878,15 @@ func BenchmarkModf(b *testing.B) {
        }
 }
 
-func BenchmarkNextafter(b *testing.B) {
+func BenchmarkNextafter32(b *testing.B) {
+       for i := 0; i < b.N; i++ {
+               Nextafter32(.5, 1)
+       }
+}
+
+func BenchmarkNextafter64(b *testing.B) {
        for i := 0; i < b.N; i++ {
-               Nextafter(.5, 1)
+               Nextafter64(.5, 1)
        }
 }
 
index 7c4b5bcdfef7eb2a5a58e0a73d285aada804f01c..fab1ad267e40806a9e4ce975059fb3ba0fe3f29a 100644 (file)
@@ -4,13 +4,33 @@
 
 package math
 
-// Nextafter returns the next representable value after x towards y.
-// If x == y, then x is returned.
-//
-// Special cases are:
-//      Nextafter(NaN, y) = NaN
-//      Nextafter(x, NaN) = NaN
-func Nextafter(x, y float64) (r float64) {
+// Nextafter32 returns the next representable float32 value after x towards y.
+// Special cases:
+//     Nextafter32(x, x)   = x
+//      Nextafter32(NaN, y) = NaN
+//      Nextafter32(x, NaN) = NaN
+func Nextafter32(x, y float32) (r float32) {
+       switch {
+       case IsNaN(float64(x)) || IsNaN(float64(y)): // special case
+               r = float32(NaN())
+       case x == y:
+               r = x
+       case x == 0:
+               r = float32(Copysign(float64(Float32frombits(1)), float64(y)))
+       case (y > x) == (x > 0):
+               r = Float32frombits(Float32bits(x) + 1)
+       default:
+               r = Float32frombits(Float32bits(x) - 1)
+       }
+       return
+}
+
+// Nextafter64 returns the next representable float64 value after x towards y.
+// Special cases:
+//     Nextafter64(x, x)   = x
+//      Nextafter64(NaN, y) = NaN
+//      Nextafter64(x, NaN) = NaN
+func Nextafter64(x, y float64) (r float64) {
        switch {
        case IsNaN(x) || IsNaN(y): // special case
                r = NaN()
@@ -25,3 +45,9 @@ func Nextafter(x, y float64) (r float64) {
        }
        return
 }
+
+// Nextafter is the same as Nextafter64.
+// It is provided for backward-compatibility only.
+func Nextafter(x, y float64) float64 {
+       return Nextafter64(x, y)
+}