aboutsummaryrefslogtreecommitdiff
path: root/src/fmt
diff options
context:
space:
mode:
authorDave Brophy <dave@brophy.uk>2018-08-28 18:13:40 +0000
committerRob Pike <r@golang.org>2018-08-28 20:15:15 +0000
commit7c7cecc1846aaaa0ce73931644fe1df2b4559e09 (patch)
treeb600b7702a813600bf4634734ae3ea93c8b38e25 /src/fmt
parentcb7f9ec4b71e81760fa36ebff60a7e41a07df238 (diff)
downloadgo-7c7cecc1846aaaa0ce73931644fe1df2b4559e09.tar.gz
go-7c7cecc1846aaaa0ce73931644fe1df2b4559e09.zip
fmt: fix incorrect format of whole-number floats when using %#v
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>
Diffstat (limited to 'src/fmt')
-rw-r--r--src/fmt/fmt_test.go8
-rw-r--r--src/fmt/format.go41
2 files changed, 34 insertions, 15 deletions
diff --git a/src/fmt/fmt_test.go b/src/fmt/fmt_test.go
index edfd1ee824..9581becd32 100644
--- a/src/fmt/fmt_test.go
+++ b/src/fmt/fmt_test.go
@@ -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)"},
diff --git a/src/fmt/format.go b/src/fmt/format.go
index 91103f2c07..3a3cd8d1a1 100644
--- a/src/fmt/format.go
+++ b/src/fmt/format.go
@@ -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...)
}