mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
fmt: fix incorrect format of whole-number floats when using %#v
This fixes the unwanted behaviour where printing a zero float with the 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
This commit is contained in:
parent
00ebfcde7f
commit
adfb061363
|
@ -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)"},
|
||||
|
|
|
@ -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...)
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue