]> Cypherpunks repositories - gostls13.git/commitdiff
math/big: add more Float.Float64 conversion tests
authorRobert Griesemer <gri@golang.org>
Fri, 22 May 2015 00:52:49 +0000 (17:52 -0700)
committerRobert Griesemer <gri@golang.org>
Fri, 22 May 2015 21:06:01 +0000 (21:06 +0000)
- structure the Float64 conversion tests the same way as for Float32
- add additional test cases, including one that exposes a current issue
  (currently disabled, same issue as was fixed for Float32)

The Float64 fix will be in a subsequent change for easier reviewing.

Change-Id: I95dc9e8d1f6b6073a98c7bc2289e6d3248fc3420
Reviewed-on: https://go-review.googlesource.com/10351
Reviewed-by: Alan Donovan <adonovan@google.com>
src/math/big/float_test.go

index 4da145b6523dbc34c5838fda1f88733d14917b30..92eec71c5fc2c4dca94bc3211697046a8fe9ffe1 100644 (file)
@@ -209,6 +209,12 @@ func alike32(x, y float32) bool {
 
 }
 
+func alike64(x, y float64) bool {
+       // we can ignore NaNs
+       return x == y && math.Signbit(x) == math.Signbit(y)
+
+}
+
 func TestFloatMantExp(t *testing.T) {
        for _, test := range []struct {
                x    string
@@ -908,35 +914,37 @@ func TestFloatFloat64(t *testing.T) {
                out float64
                acc Accuracy
        }{
-               {"-Inf", math.Inf(-1), Exact},
-               {"-0x1.fffffffffffff8p2147483646", -math.Inf(+1), Below}, // overflow in rounding
-               {"-1e10000", math.Inf(-1), Below},                        // overflow
-               {"-0x1p1024", math.Inf(-1), Below},                       // overflow
-               {"-0x1.fffffffffffff8p1023", -math.Inf(+1), Below},       // overflow
-               {"-0x1.fffffffffffff4p1023", -math.MaxFloat64, Above},
-               {"-0x1.fffffffffffff0p1023", -math.MaxFloat64, Exact},
-               {"-12345.000000000000000000001", -12345, Above},
-               {"-12345.0", -12345, Exact},
-               {"-1.000000000000000000001", -1, Above},
-               {"-1", -1, Exact},
-               {"-0x0.0000000000001p-1022", -math.SmallestNonzeroFloat64, Exact},
-               {"-0x0.0000000000001p-1023", -0, Above}, // underflow
-               {"-1e-1000", -0, Above},                 // underflow
                {"0", 0, Exact},
-               {"1e-1000", 0, Below},                 // underflow
-               {"0x0.0000000000001p-1023", 0, Below}, // underflow
-               {"0x0.0000000000001p-1022", math.SmallestNonzeroFloat64, Exact},
+
+               // underflow
+               {"1e-1000", 0, Below},
+               {"0x0.0000000000001p-1023", 0, Below},
+               {"0x0.00000000000008p-1022", 0, Below},
+
+               // denormals
+               // TODO(gri) enable once Float64 is fixed
+               // {"0x0.0000000000000cp-1022", math.SmallestNonzeroFloat64, Above}, // rounded up to smallest denormal
+               {"0x0.0000000000001p-1022", math.SmallestNonzeroFloat64, Exact}, // smallest denormal
+               {"0x.8p-1073", math.SmallestNonzeroFloat64, Exact},
+               {"1p-1074", math.SmallestNonzeroFloat64, Exact},
+               {"0x.fffffffffffffp-1022", math.Float64frombits(0x000fffffffffffff), Exact}, // largest denormal
+
+               // normals
+               {"0x.fffffffffffff8p-1022", math.Float64frombits(0x0010000000000000), Above}, // rounded up to smallest normal
+               {"1p-1022", math.Float64frombits(0x0010000000000000), Exact},                 // smallest normal
                {"1", 1, Exact},
                {"1.000000000000000000001", 1, Below},
                {"12345.0", 12345, Exact},
                {"12345.000000000000000000001", 12345, Below},
                {"0x1.fffffffffffff0p1023", math.MaxFloat64, Exact},
                {"0x1.fffffffffffff4p1023", math.MaxFloat64, Below},
-               {"0x1.fffffffffffff8p1023", math.Inf(+1), Above},       // overflow
-               {"0x1p1024", math.Inf(+1), Above},                      // overflow
-               {"1e10000", math.Inf(+1), Above},                       // overflow
+
+               // overflow
+               {"0x1.fffffffffffff8p1023", math.Inf(+1), Above},
+               {"0x1p1024", math.Inf(+1), Above},
+               {"1e10000", math.Inf(+1), Above},
                {"0x1.fffffffffffff8p2147483646", math.Inf(+1), Above}, // overflow in rounding
-               {"+Inf", math.Inf(+1), Exact},
+               {"Inf", math.Inf(+1), Exact},
 
                // selected denormalized values that were handled incorrectly in the past
                {"0x.fffffffffffffp-1022", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact},
@@ -947,22 +955,32 @@ func TestFloatFloat64(t *testing.T) {
                // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
                {"2.2250738585072012e-308", 2.2250738585072014e-308, Above},
        } {
-               // conversion should match strconv where syntax is agreeable
-               if f, err := strconv.ParseFloat(test.x, 64); err == nil && f != test.out {
-                       t.Errorf("%s: got %g; want %g (incorrect test data)", test.x, f, test.out)
-               }
+               for i := 0; i < 2; i++ {
+                       // test both signs
+                       tx, tout, tacc := test.x, test.out, test.acc
+                       if i != 0 {
+                               tx = "-" + tx
+                               tout = -tout
+                               tacc = -tacc
+                       }
 
-               x := makeFloat(test.x)
-               out, acc := x.Float64()
-               if out != test.out || acc != test.acc {
-                       t.Errorf("%s: got %g (%#x, %s); want %g (%#x, %s)", test.x, out, math.Float64bits(out), acc, test.out, math.Float64bits(test.out), test.acc)
-               }
+                       // conversion should match strconv where syntax is agreeable
+                       if f, err := strconv.ParseFloat(tx, 64); err == nil && !alike64(f, tout) {
+                               t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout)
+                       }
 
-               // test that x.SetFloat64(f).Float64() == f
-               var x2 Float
-               out2, acc2 := x2.SetFloat64(out).Float64()
-               if out2 != out || acc2 != Exact {
-                       t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
+                       x := makeFloat(tx)
+                       out, acc := x.Float64()
+                       if !alike64(out, tout) || acc != tacc {
+                               t.Errorf("%s: got %g (%#x, %s); want %g (%#x, %s)", tx, out, math.Float64bits(out), acc, test.out, math.Float64bits(test.out), tacc)
+                       }
+
+                       // test that x.SetFloat64(f).Float64() == f
+                       var x2 Float
+                       out2, acc2 := x2.SetFloat64(out).Float64()
+                       if !alike64(out2, out) || acc2 != Exact {
+                               t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
+                       }
                }
        }
 }