]> Cypherpunks repositories - gostls13.git/commitdiff
fmt: fix incorrect format of whole-number floats when using %#v
authorDave Brophy <dave@brophy.uk>
Tue, 28 Aug 2018 18:13:40 +0000 (18:13 +0000)
committerRob Pike <r@golang.org>
Tue, 28 Aug 2018 20:15:15 +0000 (20:15 +0000)
This fixes the unwanted behaviour where printing a zero float with the
#v fmt verb outputs "0" - e.g. missing the trailing decimal. This means
that the output would be interpreted as an int rather than a float when
parsed as Go source. After this change the the output is "0.0".

Fixes #26363

Change-Id: Ic5c060522459cd5ce077675d47c848b22ddc34fa
GitHub-Last-Rev: adfb061363f0566acec134c81be9a3dcb1f4cac8
GitHub-Pull-Request: golang/go#26383
Reviewed-on: https://go-review.googlesource.com/123956
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/fmt/fmt_test.go
src/fmt/format.go
test/switch5.go

index edfd1ee824fd47efc53179b55a1ff1f1815f5492..9581becd32c3b63727285bf1ee3d56c07b446573 100644 (file)
@@ -690,6 +690,14 @@ var fmtTests = []struct {
        {"%#v", []int32(nil), "[]int32(nil)"},
        {"%#v", 1.2345678, "1.2345678"},
        {"%#v", float32(1.2345678), "1.2345678"},
+
+       // Whole number floats should have a single trailing zero added, but not
+       // for exponent notation.
+       {"%#v", 1.0, "1.0"},
+       {"%#v", 1000000.0, "1e+06"},
+       {"%#v", float32(1.0), "1.0"},
+       {"%#v", float32(1000000.0), "1e+06"},
+
        // Only print []byte and []uint8 as type []byte if they appear at the top level.
        {"%#v", []byte(nil), "[]byte(nil)"},
        {"%#v", []uint8(nil), "[]byte(nil)"},
index 91103f2c07f1804af09fc0cac9fb4282c6c762dd..3a3cd8d1a1eb0adfeb40faee208042322495452c 100644 (file)
@@ -481,15 +481,19 @@ func (f *fmt) fmtFloat(v float64, size int, verb rune, prec int) {
                return
        }
        // The sharp flag forces printing a decimal point for non-binary formats
-       // and retains trailing zeros, which we may need to restore.
-       if f.sharp && verb != 'b' {
+       // and retains trailing zeros, which we may need to restore. For the sharpV
+       // flag, we ensure a single trailing zero is present if the output is not
+       // in exponent notation.
+       if f.sharpV || (f.sharp && verb != 'b') {
                digits := 0
-               switch verb {
-               case 'v', 'g', 'G':
-                       digits = prec
-                       // If no precision is set explicitly use a precision of 6.
-                       if digits == -1 {
-                               digits = 6
+               if !f.sharpV {
+                       switch verb {
+                       case 'g', 'G':
+                               digits = prec
+                               // If no precision is set explicitly use a precision of 6.
+                               if digits == -1 {
+                                       digits = 6
+                               }
                        }
                }
 
@@ -498,25 +502,32 @@ func (f *fmt) fmtFloat(v float64, size int, verb rune, prec int) {
                var tailBuf [5]byte
                tail := tailBuf[:0]
 
-               hasDecimalPoint := false
+               var hasDecimalPoint, hasExponent bool
                // Starting from i = 1 to skip sign at num[0].
                for i := 1; i < len(num); i++ {
                        switch num[i] {
                        case '.':
                                hasDecimalPoint = true
                        case 'e', 'E':
+                               hasExponent = true
                                tail = append(tail, num[i:]...)
                                num = num[:i]
                        default:
                                digits--
                        }
                }
-               if !hasDecimalPoint {
-                       num = append(num, '.')
-               }
-               for digits > 0 {
-                       num = append(num, '0')
-                       digits--
+               if f.sharpV {
+                       if !hasDecimalPoint && !hasExponent {
+                               num = append(num, '.', '0')
+                       }
+               } else {
+                       if !hasDecimalPoint {
+                               num = append(num, '.')
+                       }
+                       for digits > 0 {
+                               num = append(num, '0')
+                               digits--
+                       }
                }
                num = append(num, tail...)
        }
index ce95bf8d7b1b4f8c7328900ec18e64b50d091e00..6641d582bcbaf74a3881228453851c45a4fbf388 100644 (file)
@@ -24,8 +24,8 @@ func f0(x int) {
 func f1(x float32) {
        switch x {
        case 5:
-       case 5: // ERROR "duplicate case 5 in switch"
-       case 5.0: // ERROR "duplicate case 5 in switch"
+       case 5: // ERROR "duplicate case 5 .value 5\.0. in switch"
+       case 5.0: // ERROR "duplicate case 5 .value 5\.0. in switch"
        }
 }
 
@@ -44,9 +44,9 @@ func f3(e interface{}) {
        case 0: // ERROR "duplicate case 0 in switch"
        case int64(0):
        case float32(10):
-       case float32(10): // ERROR "duplicate case float32\(10\) .value 10. in switch"
+       case float32(10): // ERROR "duplicate case float32\(10\) .value 10\.0. in switch"
        case float64(10):
-       case float64(10): // ERROR "duplicate case float64\(10\) .value 10. in switch"
+       case float64(10): // ERROR "duplicate case float64\(10\) .value 10\.0. in switch"
        }
 }