From d5b5d6702ad7d64f189c915225b945a2aa471a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Mo=CC=88hrmann?= Date: Fri, 13 Feb 2015 15:59:54 +0100 Subject: [PATCH] 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 --- src/strconv/ftoa.go | 50 +++++++++++++++------------------------- src/strconv/ftoa_test.go | 1 + 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/src/strconv/ftoa.go b/src/strconv/ftoa.go index f885d96e9c..d59c78e493 100644 --- a/src/strconv/ftoa.go +++ b/src/strconv/ftoa.go @@ -47,7 +47,7 @@ func FormatFloat(f float64, fmt byte, prec, bitSize int) string { // 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 @@ func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte { 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 39b861547e..1b4dcd945b 100644 --- a/src/strconv/ftoa_test.go +++ b/src/strconv/ftoa_test.go @@ -227,6 +227,7 @@ func BenchmarkAppendFloatNegExp(b *testing.B) { benchmarkAppendFloat(b, -5.11e- 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) }