aboutsummaryrefslogtreecommitdiff
path: root/src/strconv/atof_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/strconv/atof_test.go')
-rw-r--r--src/strconv/atof_test.go60
1 files changed, 58 insertions, 2 deletions
diff --git a/src/strconv/atof_test.go b/src/strconv/atof_test.go
index 545d989c41..3c058b9be5 100644
--- a/src/strconv/atof_test.go
+++ b/src/strconv/atof_test.go
@@ -303,6 +303,12 @@ var atoftests = []atofTest{
{"1.00000000000000033306690738754696212708950042724609375", "1.0000000000000004", nil},
{"0x1.00000000000018p0", "1.0000000000000004", nil},
+ // Halfway between 1090544144181609278303144771584 and 1090544144181609419040633126912
+ // (15497564393479157p+46, should round to even 15497564393479156p+46, issue 36657)
+ {"1090544144181609348671888949248", "1.0905441441816093e+30", nil},
+ // slightly above, rounds up
+ {"1090544144181609348835077142190", "1.0905441441816094e+30", nil},
+
// Underscores.
{"1_23.50_0_0e+1_2", "1.235e+14", nil},
{"-_123.5e+12", "0", ErrSyntax},
@@ -628,6 +634,23 @@ func TestRoundTrip32(t *testing.T) {
t.Logf("tested %d float32's", count)
}
+// Issue 42297: a lot of code in the wild accidentally calls ParseFloat(s, 10)
+// or ParseFloat(s, 0), so allow bitSize values other than 32 and 64.
+func TestParseFloatIncorrectBitSize(t *testing.T) {
+ const s = "1.5e308"
+ const want = 1.5e308
+
+ for _, bitSize := range []int{0, 10, 100, 128} {
+ f, err := ParseFloat(s, bitSize)
+ if err != nil {
+ t.Fatalf("ParseFloat(%q, %d) gave error %s", s, bitSize, err)
+ }
+ if f != want {
+ t.Fatalf("ParseFloat(%q, %d) = %g (expected %g)", s, bitSize, f, want)
+ }
+ }
+}
+
func BenchmarkAtof64Decimal(b *testing.B) {
for i := 0; i < b.N; i++ {
ParseFloat("33909", 64)
@@ -653,17 +676,38 @@ func BenchmarkAtof64Big(b *testing.B) {
}
func BenchmarkAtof64RandomBits(b *testing.B) {
+ initAtof()
+ b.ResetTimer()
for i := 0; i < b.N; i++ {
ParseFloat(benchmarksRandomBits[i%1024], 64)
}
}
func BenchmarkAtof64RandomFloats(b *testing.B) {
+ initAtof()
+ b.ResetTimer()
for i := 0; i < b.N; i++ {
ParseFloat(benchmarksRandomNormal[i%1024], 64)
}
}
+func BenchmarkAtof64RandomLongFloats(b *testing.B) {
+ initAtof()
+ samples := make([]string, len(atofRandomTests))
+ for i, t := range atofRandomTests {
+ samples[i] = FormatFloat(t.x, 'g', 20, 64)
+ }
+ b.ResetTimer()
+ idx := 0
+ for i := 0; i < b.N; i++ {
+ ParseFloat(samples[idx], 64)
+ idx++
+ if idx == len(samples) {
+ idx = 0
+ }
+ }
+}
+
func BenchmarkAtof32Decimal(b *testing.B) {
for i := 0; i < b.N; i++ {
ParseFloat("33909", 32)
@@ -682,10 +726,9 @@ func BenchmarkAtof32FloatExp(b *testing.B) {
}
}
-var float32strings [4096]string
-
func BenchmarkAtof32Random(b *testing.B) {
n := uint32(997)
+ var float32strings [4096]string
for i := range float32strings {
n = (99991*n + 42) % (0xff << 23)
float32strings[i] = FormatFloat(float64(math.Float32frombits(n)), 'g', -1, 32)
@@ -695,3 +738,16 @@ func BenchmarkAtof32Random(b *testing.B) {
ParseFloat(float32strings[i%4096], 32)
}
}
+
+func BenchmarkAtof32RandomLong(b *testing.B) {
+ n := uint32(997)
+ var float32strings [4096]string
+ for i := range float32strings {
+ n = (99991*n + 42) % (0xff << 23)
+ float32strings[i] = FormatFloat(float64(math.Float32frombits(n)), 'g', 20, 32)
+ }
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ ParseFloat(float32strings[i%4096], 32)
+ }
+}