return float32(f), n, err
}
- if optimize && !trunc {
+ if optimize {
// Try pure floating-point arithmetic conversion, and if that fails,
// the Eisel-Lemire algorithm.
- if f, ok := atof32exact(mantissa, exp, neg); ok {
- return f, n, nil
+ if !trunc {
+ if f, ok := atof32exact(mantissa, exp, neg); ok {
+ return f, n, nil
+ }
}
- if f, ok := eiselLemire32(mantissa, exp, neg); ok {
- return f, n, nil
+ f, ok := eiselLemire32(mantissa, exp, neg)
+ if ok {
+ if !trunc {
+ return f, n, nil
+ }
+ // Even if the mantissa was truncated, we may
+ // have found the correct result. Confirm by
+ // converting the upper mantissa bound.
+ fUp, ok := eiselLemire32(mantissa+1, exp, neg)
+ if ok && f == fUp {
+ return f, n, nil
+ }
}
}
return f, n, err
}
- if optimize && !trunc {
+ if optimize {
// Try pure floating-point arithmetic conversion, and if that fails,
// the Eisel-Lemire algorithm.
- if f, ok := atof64exact(mantissa, exp, neg); ok {
- return f, n, nil
+ if !trunc {
+ if f, ok := atof64exact(mantissa, exp, neg); ok {
+ return f, n, nil
+ }
}
- if f, ok := eiselLemire64(mantissa, exp, neg); ok {
- return f, n, nil
+ f, ok := eiselLemire64(mantissa, exp, neg)
+ if ok {
+ if !trunc {
+ return f, n, nil
+ }
+ // Even if the mantissa was truncated, we may
+ // have found the correct result. Confirm by
+ // converting the upper mantissa bound.
+ fUp, ok := eiselLemire64(mantissa+1, exp, neg)
+ if ok && f == fUp {
+ return f, n, nil
+ }
}
}
}
}
+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)
}
}
-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)
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)
+ }
+}