aboutsummaryrefslogtreecommitdiff
path: root/src/math/big/float_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/math/big/float_test.go')
-rw-r--r--src/math/big/float_test.go212
1 files changed, 126 insertions, 86 deletions
diff --git a/src/math/big/float_test.go b/src/math/big/float_test.go
index 5b5a0247b1..7df9fc74bc 100644
--- a/src/math/big/float_test.go
+++ b/src/math/big/float_test.go
@@ -203,6 +203,18 @@ func alike(x, y *Float) bool {
return x.Cmp(y) == 0 && x.Signbit() == y.Signbit()
}
+func alike32(x, y float32) bool {
+ // we can ignore NaNs
+ return x == y && math.Signbit(float64(x)) == math.Signbit(float64(y))
+
+}
+
+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
@@ -828,52 +840,69 @@ func TestFloatFloat32(t *testing.T) {
out float32
acc Accuracy
}{
- {"-Inf", float32(math.Inf(-1)), Exact},
- {"-0x1.ffffff0p2147483646", float32(-math.Inf(+1)), Below}, // overflow in rounding
- {"-1e10000", float32(math.Inf(-1)), Below}, // overflow
- {"-0x1p128", float32(math.Inf(-1)), Below}, // overflow
- {"-0x1.ffffff0p127", float32(-math.Inf(+1)), Below}, // overflow
- {"-0x1.fffffe8p127", -math.MaxFloat32, Above},
- {"-0x1.fffffe0p127", -math.MaxFloat32, Exact},
- {"-12345.000000000000000000001", -12345, Above},
- {"-12345.0", -12345, Exact},
- {"-1.000000000000000000001", -1, Above},
- {"-1", -1, Exact},
- {"-0x0.000002p-126", -math.SmallestNonzeroFloat32, Exact},
- {"-0x0.000002p-127", -0, Above}, // underflow
- {"-1e-1000", -0, Above}, // underflow
{"0", 0, Exact},
- {"1e-1000", 0, Below}, // underflow
- {"0x0.000002p-127", 0, Below}, // underflow
- {"0x0.000002p-126", math.SmallestNonzeroFloat32, Exact},
+
+ // underflow
+ {"1e-1000", 0, Below},
+ {"0x0.000002p-127", 0, Below},
+ {"0x.0000010p-126", 0, Below},
+
+ // denormals
+ {"1.401298464e-45", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
+ {"0x.ffffff8p-149", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
+ {"0x.0000018p-126", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
+ {"0x.0000020p-126", math.SmallestNonzeroFloat32, Exact},
+ {"0x.8p-148", math.SmallestNonzeroFloat32, Exact},
+ {"1p-149", math.SmallestNonzeroFloat32, Exact},
+ {"0x.fffffep-126", math.Float32frombits(0x7fffff), Exact}, // largest denormal
+
+ // normals
+ {"0x.ffffffp-126", math.Float32frombits(0x00800000), Above}, // rounded up to smallest normal
+ {"1p-126", math.Float32frombits(0x00800000), Exact}, // smallest normal
+ {"0x1.fffffep-126", math.Float32frombits(0x00ffffff), Exact},
+ {"0x1.ffffffp-126", math.Float32frombits(0x01000000), Above}, // rounded up
{"1", 1, Exact},
{"1.000000000000000000001", 1, Below},
{"12345.0", 12345, Exact},
{"12345.000000000000000000001", 12345, Below},
{"0x1.fffffe0p127", math.MaxFloat32, Exact},
{"0x1.fffffe8p127", math.MaxFloat32, Below},
- {"0x1.ffffff0p127", float32(math.Inf(+1)), Above}, // overflow
- {"0x1p128", float32(math.Inf(+1)), Above}, // overflow
- {"1e10000", float32(math.Inf(+1)), Above}, // overflow
+
+ // overflow
+ {"0x1.ffffff0p127", float32(math.Inf(+1)), Above},
+ {"0x1p128", float32(math.Inf(+1)), Above},
+ {"1e10000", float32(math.Inf(+1)), Above},
{"0x1.ffffff0p2147483646", float32(math.Inf(+1)), Above}, // overflow in rounding
- {"+Inf", float32(math.Inf(+1)), Exact},
+
+ // inf
+ {"Inf", float32(math.Inf(+1)), Exact},
} {
- // conversion should match strconv where syntax is agreeable
- if f, err := strconv.ParseFloat(test.x, 32); err == nil && float32(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.Float32()
- if out != test.out || acc != test.acc {
- t.Errorf("%s: got %g (%#x, %s); want %g (%#x, %s)", test.x, out, math.Float32bits(out), acc, test.out, math.Float32bits(test.out), test.acc)
- }
+ // conversion should match strconv where syntax is agreeable
+ if f, err := strconv.ParseFloat(tx, 32); err == nil && !alike32(float32(f), tout) {
+ t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout)
+ }
- // test that x.SetFloat64(float64(f)).Float32() == f
- var x2 Float
- out2, acc2 := x2.SetFloat64(float64(out)).Float32()
- if out2 != out || acc2 != Exact {
- t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
+ x := makeFloat(tx)
+ out, acc := x.Float32()
+ if !alike32(out, tout) || acc != tacc {
+ t.Errorf("%s: got %g (%#x, %s); want %g (%#x, %s)", tx, out, math.Float32bits(out), acc, test.out, math.Float32bits(test.out), tacc)
+ }
+
+ // test that x.SetFloat64(float64(f)).Float32() == f
+ var x2 Float
+ out2, acc2 := x2.SetFloat64(float64(out)).Float32()
+ if !alike32(out2, out) || acc2 != Exact {
+ t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
+ }
}
}
}
@@ -885,35 +914,36 @@ 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
+ {"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},
@@ -924,22 +954,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)
+ }
}
}
}
@@ -1523,32 +1563,32 @@ func TestFloatArithmeticOverflow(t *testing.T) {
x, y, want string
acc Accuracy
}{
- {4, ToNearestEven, '+', "0", "0", "0", Exact}, // smoke test
- {4, ToNearestEven, '+', "0x.8p0", "0x.8p0", "0x.8p1", Exact}, // smoke test
+ {4, ToNearestEven, '+', "0", "0", "0", Exact}, // smoke test
+ {4, ToNearestEven, '+', "0x.8p+0", "0x.8p+0", "0x.8p+1", Exact}, // smoke test
- {4, ToNearestEven, '+', "0", "0x.8p2147483647", "0x.8p2147483647", Exact},
- {4, ToNearestEven, '+', "0x.8p2147483500", "0x.8p2147483647", "0x.8p2147483647", Below}, // rounded to zero
- {4, ToNearestEven, '+', "0x.8p2147483647", "0x.8p2147483647", "+Inf", Above}, // exponent overflow in +
- {4, ToNearestEven, '+', "-0x.8p2147483647", "-0x.8p2147483647", "-Inf", Below}, // exponent overflow in +
- {4, ToNearestEven, '-', "-0x.8p2147483647", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in -
+ {4, ToNearestEven, '+', "0", "0x.8p2147483647", "0x.8p+2147483647", Exact},
+ {4, ToNearestEven, '+', "0x.8p2147483500", "0x.8p2147483647", "0x.8p+2147483647", Below}, // rounded to zero
+ {4, ToNearestEven, '+', "0x.8p2147483647", "0x.8p2147483647", "+Inf", Above}, // exponent overflow in +
+ {4, ToNearestEven, '+', "-0x.8p2147483647", "-0x.8p2147483647", "-Inf", Below}, // exponent overflow in +
+ {4, ToNearestEven, '-', "-0x.8p2147483647", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in -
- {4, ToZero, '+', "0x.fp2147483647", "0x.8p2147483643", "0x.fp2147483647", Below}, // rounded to zero
- {4, ToNearestEven, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above}, // exponent overflow in rounding
- {4, AwayFromZero, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above}, // exponent overflow in rounding
+ {4, ToZero, '+', "0x.fp2147483647", "0x.8p2147483643", "0x.fp+2147483647", Below}, // rounded to zero
+ {4, ToNearestEven, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above}, // exponent overflow in rounding
+ {4, AwayFromZero, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above}, // exponent overflow in rounding
- {4, AwayFromZero, '-', "-0x.fp2147483647", "0x.8p2147483644", "-Inf", Below}, // exponent overflow in rounding
- {4, ToNearestEven, '-', "-0x.fp2147483647", "0x.8p2147483643", "-Inf", Below}, // exponent overflow in rounding
- {4, ToZero, '-', "-0x.fp2147483647", "0x.8p2147483643", "-0x.fp2147483647", Above}, // rounded to zero
+ {4, AwayFromZero, '-', "-0x.fp2147483647", "0x.8p2147483644", "-Inf", Below}, // exponent overflow in rounding
+ {4, ToNearestEven, '-', "-0x.fp2147483647", "0x.8p2147483643", "-Inf", Below}, // exponent overflow in rounding
+ {4, ToZero, '-', "-0x.fp2147483647", "0x.8p2147483643", "-0x.fp+2147483647", Above}, // rounded to zero
{4, ToNearestEven, '+', "0", "0x.8p-2147483648", "0x.8p-2147483648", Exact},
{4, ToNearestEven, '+', "0x.8p-2147483648", "0x.8p-2147483648", "0x.8p-2147483647", Exact},
- {4, ToNearestEven, '*', "1", "0x.8p2147483647", "0x.8p2147483647", Exact},
+ {4, ToNearestEven, '*', "1", "0x.8p2147483647", "0x.8p+2147483647", Exact},
{4, ToNearestEven, '*', "2", "0x.8p2147483647", "+Inf", Above}, // exponent overflow in *
{4, ToNearestEven, '*', "-2", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in *
{4, ToNearestEven, '/', "0.5", "0x.8p2147483647", "0x.8p-2147483646", Exact},
- {4, ToNearestEven, '/', "0x.8p0", "0x.8p2147483647", "0x.8p-2147483646", Exact},
+ {4, ToNearestEven, '/', "0x.8p+0", "0x.8p2147483647", "0x.8p-2147483646", Exact},
{4, ToNearestEven, '/', "0x.8p-1", "0x.8p2147483647", "0x.8p-2147483647", Exact},
{4, ToNearestEven, '/', "0x.8p-2", "0x.8p2147483647", "0x.8p-2147483648", Exact},
{4, ToNearestEven, '/', "0x.8p-3", "0x.8p2147483647", "0", Below}, // exponent underflow in /
@@ -1659,7 +1699,7 @@ func TestFloatCmpSpecialValues(t *testing.T) {
want = +1
}
if got != want {
- t.Errorf("(%g).Cmp(%g) = %s; want %s", x, y, got, want)
+ t.Errorf("(%g).Cmp(%g) = %v; want %v", x, y, got, want)
}
}
}