strconv: simplify code for binary exponent float format
Use optimized formatBits function to format mantissa and exponent.
Add benchmark for binary exponent float format.
on darwin/386
benchmark old ns/op new ns/op delta
BenchmarkAppendFloatBinaryExp 520 122 -76.54%
on darwin/amd64
benchmark old ns/op new ns/op delta
BenchmarkAppendFloatBinaryExp 76.9 84.3 +9.62%
Change-Id: If543552f1960e1655bed3a4130914e5eaa3aac69
Reviewed-on: https://go-review.googlesource.com/5600
Reviewed-by: Robert Griesemer <gri@golang.org>
diff --git a/src/strconv/ftoa.go b/src/strconv/ftoa.go
index f885d96..d59c78e 100644
--- a/src/strconv/ftoa.go
+++ b/src/strconv/ftoa.go
@@ -47,7 +47,7 @@
// AppendFloat appends the string form of the floating-point number f,
// as generated by FormatFloat, to dst and returns the extended buffer.
-func AppendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte {
+func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte {
return genericFtoa(dst, f, fmt, prec, bitSize)
}
@@ -418,39 +418,27 @@
return dst
}
-// %b: -ddddddddp+ddd
+// %b: -ddddddddp±ddd
func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
- var buf [50]byte
- w := len(buf)
- exp -= int(flt.mantbits)
- esign := byte('+')
- if exp < 0 {
- esign = '-'
- exp = -exp
- }
- n := 0
- for exp > 0 || n < 1 {
- n++
- w--
- buf[w] = byte(exp%10 + '0')
- exp /= 10
- }
- w--
- buf[w] = esign
- w--
- buf[w] = 'p'
- n = 0
- for mant > 0 || n < 1 {
- n++
- w--
- buf[w] = byte(mant%10 + '0')
- mant /= 10
- }
+ // sign
if neg {
- w--
- buf[w] = '-'
+ dst = append(dst, '-')
}
- return append(dst, buf[w:]...)
+
+ // mantissa
+ dst, _ = formatBits(dst, mant, 10, false, true)
+
+ // p
+ dst = append(dst, 'p')
+
+ // ±exponent
+ exp -= int(flt.mantbits)
+ if exp >= 0 {
+ dst = append(dst, '+')
+ }
+ dst, _ = formatBits(dst, uint64(exp), 10, exp < 0, true)
+
+ return dst
}
func min(a, b int) int {
diff --git a/src/strconv/ftoa_test.go b/src/strconv/ftoa_test.go
index 39b8615..1b4dcd9 100644
--- a/src/strconv/ftoa_test.go
+++ b/src/strconv/ftoa_test.go
@@ -227,6 +227,7 @@
func BenchmarkAppendFloatBig(b *testing.B) {
benchmarkAppendFloat(b, 123456789123456789123456789, 'g', -1, 64)
}
+func BenchmarkAppendFloatBinaryExp(b *testing.B) { benchmarkAppendFloat(b, -1, 'b', -1, 64) }
func BenchmarkAppendFloat32Integer(b *testing.B) { benchmarkAppendFloat(b, 33909, 'g', -1, 32) }
func BenchmarkAppendFloat32ExactFraction(b *testing.B) { benchmarkAppendFloat(b, 3.375, 'g', -1, 32) }