1
0
mirror of https://github.com/golang/go synced 2024-11-05 14:56:10 -07:00

math/big: add more Float.Float64 conversion tests

- 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>
This commit is contained in:
Robert Griesemer 2015-05-21 17:52:49 -07:00
parent 79afb43a0a
commit 8de8925c77

View 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)
}
}
}
}