Skip to content

Commit fceeadd

Browse files
committed
fmt: fix incorrect format of whole-number floats when using %#v
Fixes golang#26363
1 parent 8a33045 commit fceeadd

File tree

2 files changed

+31
-14
lines changed

2 files changed

+31
-14
lines changed

src/fmt/fmt_test.go

+6
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,12 @@ var fmtTests = []struct {
690690
{"%#v", []int32(nil), "[]int32(nil)"},
691691
{"%#v", 1.2345678, "1.2345678"},
692692
{"%#v", float32(1.2345678), "1.2345678"},
693+
// Whole number floats should have a single trailing zero added, but not when in exponent
694+
// notation:
695+
{"%#v", 1.0, "1.0"},
696+
{"%#v", 1000000.0, "1e+06"},
697+
{"%#v", float32(1.0), "1.0"},
698+
{"%#v", float32(1000000.0), "1e+06"},
693699
// Only print []byte and []uint8 as type []byte if they appear at the top level.
694700
{"%#v", []byte(nil), "[]byte(nil)"},
695701
{"%#v", []uint8(nil), "[]byte(nil)"},

src/fmt/format.go

+25-14
Original file line numberDiff line numberDiff line change
@@ -482,14 +482,16 @@ func (f *fmt) fmtFloat(v float64, size int, verb rune, prec int) {
482482
}
483483
// The sharp flag forces printing a decimal point for non-binary formats
484484
// and retains trailing zeros, which we may need to restore.
485-
if f.sharp && verb != 'b' {
485+
if f.sharpV || (f.sharp && verb != 'b') {
486486
digits := 0
487-
switch verb {
488-
case 'v', 'g', 'G':
489-
digits = prec
490-
// If no precision is set explicitly use a precision of 6.
491-
if digits == -1 {
492-
digits = 6
487+
if !f.sharpV {
488+
switch verb {
489+
case 'g', 'G':
490+
digits = prec
491+
// If no precision is set explicitly use a precision of 6.
492+
if digits == -1 {
493+
digits = 6
494+
}
493495
}
494496
}
495497

@@ -498,25 +500,34 @@ func (f *fmt) fmtFloat(v float64, size int, verb rune, prec int) {
498500
var tailBuf [5]byte
499501
tail := tailBuf[:0]
500502

501-
hasDecimalPoint := false
503+
var hasDecimalPoint, hasExponent bool
502504
// Starting from i = 1 to skip sign at num[0].
503505
for i := 1; i < len(num); i++ {
504506
switch num[i] {
505507
case '.':
506508
hasDecimalPoint = true
507509
case 'e', 'E':
510+
hasExponent = true
508511
tail = append(tail, num[i:]...)
509512
num = num[:i]
510513
default:
511514
digits--
512515
}
513516
}
514-
if !hasDecimalPoint {
515-
num = append(num, '.')
516-
}
517-
for digits > 0 {
518-
num = append(num, '0')
519-
digits--
517+
if f.sharpV {
518+
if !hasDecimalPoint && !hasExponent {
519+
// In %#v mode, add a decimal point and a single trailing zero only if
520+
// we don't already have a decimal point or exponent notation.
521+
num = append(num, '.', '0')
522+
}
523+
} else {
524+
if !hasDecimalPoint {
525+
num = append(num, '.')
526+
}
527+
for digits > 0 {
528+
num = append(num, '0')
529+
digits--
530+
}
520531
}
521532
num = append(num, tail...)
522533
}

0 commit comments

Comments
 (0)