]> Cypherpunks repositories - gostls13.git/commitdiff
fmt: remove math package dependency and avoid float operations
authorMartin Möhrmann <martisch@uos.de>
Fri, 19 Feb 2016 21:45:38 +0000 (22:45 +0100)
committerRob Pike <r@golang.org>
Fri, 19 Feb 2016 22:55:30 +0000 (22:55 +0000)
Remove floating point comparisons and rely only on the information
directly provided by appendFloat.
Make restoring the zero padding flag explicit instead of using a defer.
Rearrange some case distinctions to remove duplicated code.
Add more test cases for zero padded floating point numbers with sign.

benchmark                   old ns/op     new ns/op     delta
BenchmarkSprintfFloat-4     187           180           -3.74%

Change-Id: Ifa2ae85257909f40b1b18118c92b516933271729
Reviewed-on: https://go-review.googlesource.com/19721
Reviewed-by: Rob Pike <r@golang.org>
src/fmt/fmt_test.go
src/fmt/format.go

index 793f709a79055fa5d25a87747b7ceb8d713a35d3..8d7c36ceb1432ef76774cf798b2a32d646f3c17a 100644 (file)
@@ -259,6 +259,12 @@ var fmtTests = []struct {
        {"%+.3F", float32(-1.0), "-1.000"},
        {"%+07.2f", 1.0, "+001.00"},
        {"%+07.2f", -1.0, "-001.00"},
+       {"%-07.2f", 1.0, "1.00   "},
+       {"%-07.2f", -1.0, "-1.00  "},
+       {"%+-07.2f", 1.0, "+1.00  "},
+       {"%+-07.2f", -1.0, "-1.00  "},
+       {"%-+07.2f", 1.0, "+1.00  "},
+       {"%-+07.2f", -1.0, "-1.00  "},
        {"%+10.2f", +1.0, "     +1.00"},
        {"%+10.2f", -1.0, "     -1.00"},
        {"% .3E", -1.0, "-1.000E+00"},
index 517b18f7d4378e3c60bc3f9c123d10273d42a2ac..bf9d00bbc03b3ae39959a78901a6a2b56687bae6 100644 (file)
@@ -5,7 +5,6 @@
 package fmt
 
 import (
-       "math"
        "strconv"
        "unicode/utf8"
 )
@@ -405,42 +404,34 @@ func doPrec(f *fmt, def int) int {
 // formatFloat formats a float64; it is an efficient equivalent to  f.pad(strconv.FormatFloat()...).
 func (f *fmt) formatFloat(v float64, verb byte, prec, n int) {
        // Format number, reserving space for leading + sign if needed.
-       num := strconv.AppendFloat(f.intbuf[0:1], v, verb, prec, n)
+       num := strconv.AppendFloat(f.intbuf[:1], v, verb, prec, n)
        if num[1] == '-' || num[1] == '+' {
                num = num[1:]
        } else {
                num[0] = '+'
        }
-       // Special handling for infinity, which doesn't look like a number so shouldn't be padded with zeros.
-       if math.IsInf(v, 0) {
-               if f.zero {
-                       defer func() { f.zero = true }()
-                       f.zero = false
-               }
-       }
-       // num is now a signed version of the number.
-       // If we're zero padding, want the sign before the leading zeros.
-       // Achieve this by writing the sign out and then padding the unsigned number.
-       if f.zero && f.widPresent && f.wid > len(num) {
-               if f.space && v >= 0 {
-                       f.buf.WriteByte(' ') // This is what C does: even with zero, f.space means space.
-                       f.wid--
-               } else if f.plus || v < 0 {
-                       f.buf.WriteByte(num[0])
-                       f.wid--
-               }
-               f.pad(num[1:])
-               return
-       }
        // f.space says to replace a leading + with a space.
        if f.space && num[0] == '+' {
                num[0] = ' '
+       }
+       // Special handling for "+Inf" and "-Inf",
+       // which don't look like a number so shouldn't be padded with zeros.
+       if num[1] == 'I' {
+               oldZero := f.zero
+               f.zero = false
                f.pad(num)
+               f.zero = oldZero
                return
        }
-       // Now we know the sign is attached directly to the number, if present at all.
-       // We want a sign if asked for, if it's negative, or if it's infinity (+Inf vs. -Inf).
-       if f.plus || num[0] == '-' || math.IsInf(v, 0) {
+       // We want a sign if asked for and if the sign is not positive.
+       if f.plus || num[0] != '+' {
+               // If we're zero padding we want the sign before the leading zeros.
+               // Achieve this by writing the sign out and then padding the unsigned number.
+               if f.zero && f.widPresent && f.wid > len(num) {
+                       f.buf.WriteByte(num[0])
+                       f.wid--
+                       num = num[1:]
+               }
                f.pad(num)
                return
        }