Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fmt: the "alternate form" (the # flag) for floating point is not supported #18857

musiphil opened this issue Jan 30, 2017 · 4 comments

fmt: the "alternate form" (the # flag) for floating point is not supported #18857

musiphil opened this issue Jan 30, 2017 · 4 comments


Copy link

@musiphil musiphil commented Jan 30, 2017

What version of Go are you using (go version)?

$ go version
go version devel +4cce27a3fa Sat Jan 21 03:20:55 2017 +0000 linux/amd64

What operating system and processor architecture are you using (go env)?

$ go env  # abridged

What did you do?

fmt.Printf("%.e\t", 1.)
fmt.Printf("%#.e\n", 1.)

fmt.Printf("%.f\t", 1.)
fmt.Printf("%#.f\n", 1.)

fmt.Printf("%.4g\t", 1.230)
fmt.Printf("%#.4g\n", 1.230)
fmt.Printf("%.4g\t", 12.30)
fmt.Printf("%#.4g\n", 12.30)
fmt.Printf("%.4g\t", 123.0)
fmt.Printf("%#.4g\n", 123.0)

What did you expect to see?

1e+00	1.e+00
1	1.
1.23	1.230
12.3	12.30
123	123.0

This is what the analogous C or C++ program produces.

In C or C++, the # flag for the floating-point (a, A, e, E, f, F, g, and G) conversions specifies that

the result of converting a floating-point number always contains a decimal-point character, even if no digits follow it. (Normally, a decimal-point character appears in the result of these conversions only if a digit follows it.)

In addition, for the g and G conversions, it specifies that

trailing zeros are not removed from the result as they would otherwise be.

Since the formatting of Go's fmt package is analogous to C's stdio functions, it's naturally expected that the former would respect this aspect as well. In particular, in a scientific context, it's crucially important to have "%#.4g" produce the same number of significant digits, either for 123.0 or 123.4; formatting 123.0 as "123" or "123." would imply only 3 significant digits, instead of 4.

What did you see instead?

1e+00	1e+00
1	1
1.23	1.23
12.3	12.3
123	123

The # flag doesn't have any effect, and the decimal-point characters and the trailing zeros are removed the formatting result.

Copy link

@ALTree ALTree commented Jan 31, 2017

@robpike robpike self-assigned this Jan 31, 2017
@robpike robpike added this to the Unplanned milestone Jan 31, 2017
Copy link

@robpike robpike commented Jan 31, 2017

I will investigate.

Copy link

@robpike robpike commented Feb 1, 2017

Amazingly, this specification was part of ANSI C89, yet I had no memory of it and neither do several other people I asked.

I would like to say that although fmt.Printf was certainly inspired by and influenced by C's printf, there is no guarantee to maintain compatibility between the two. The two libraries agree only partially and only in the handling of basic types. They diverge wildly beyond that.

That said, the feature request seems reasonable, particularly the request for a guaranteed decimal point, somewhat analogous to the # flag for %x. I therefore suggest we add this behavior. I suspect it's safe to do so as it's unlikely anyone is using %#g except in the expectation that this property will be maintained.

I stress again, though, that the issue deserves attention because it's a good idea, not because C does it this way.

@bradfitz bradfitz modified the milestones: Go1.9Maybe, Unplanned Feb 1, 2017
@martisch martisch self-assigned this Feb 15, 2017
Copy link

@gopherbot gopherbot commented Feb 15, 2017

CL mentions this issue.

@gopherbot gopherbot closed this in e97f407 Feb 19, 2017
@golang golang locked and limited conversation to collaborators Feb 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
6 participants
You can’t perform that action at this time.