golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.62k stars 17.61k forks source link

math/big: alternative format for Go syntax representation `%#v` of Int and Float #67216

Open larhun opened 5 months ago

larhun commented 5 months ago

Go version

go1.21.6 windows/amd64

Output of go env in your module/workspace:

insignificant

What did you do?

Run the snippet https://go.dev/play/p/bxXUjdjkcxQ.

What did you see happen?

Printing a big.Int and a big.Float value with the %v and %#v formats yields the same "default value".

Printing a big.Rat value %v and %#v formats yields a "default value" and a "Go-syntax representation of the value" as mandated by the fmt package.

What did you expect to see?

Printing a big.Int and a big.Float value with the %#v format should yield a "Go-syntax representation of the value" as mandated by the fmt package.

mauri870 commented 5 months ago

I'm not sure if changing this is possible, it can break existing Go programs.

cc @griesemer

larhun commented 5 months ago

The %#v is a very simple and effective printing format to log the inner structure of a value at testing. This is not possible without a fix for the current implementation of the printing formats for big.Int and big.Float. If not fixed, the documentation should be updated to clarify the bug. I prefer a fix.

JonasUnderscore commented 5 months ago
const x = 170141183460469231731687303715884105727
fmt.Printf("const x = %#v\n", new(big.Int).Not(new(big.Int).Lsh(big.NewInt(-1), x&127)))
// prints: const x = 170141183460469231731687303715884105727

I think this is a better go representation of an integer than arbitrary fields and values. Rat doesn't have any good representations other than String() -> "num/denom", so it doesn't need a Format function that overrides the fmt struct formatting.

griesemer commented 5 months ago

Arguably, for ints and floats, 42 and 42.0 are valid "Go-syntax representations of the values" and thus legitimate representations when using the %#v formats. We might even use the fractional representation, say 3/43 for rationals with the %#v format because such fractions are also "valid Go" (at least for small numerators/denominators).