Skip to content

Commit

Permalink
cmd/compile: in compiler errors, print more digits for floats close t…
Browse files Browse the repository at this point in the history
…o an int

Error messages currently print floats with %.6g, which means that if
you tried to convert something close to, but not quite, an integer, to
an integer, the error you get looks like "cannot convert 1 to type
int", when really you want "cannot convert 0.9999999 to type int".

Add more digits to floats when printing them, to make it clear that they
aren't quite integers. This helps for errors which are the result of not
being an integer. For other errors, it won't hurt much.

Fixes golang#56220

Change-Id: I7f5873af5993114a61460ef399d15316925a15a5
Reviewed-on: https://go-review.googlesource.com/c/go/+/442935
Reviewed-by: Rob Pike <r@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
  • Loading branch information
randall77 committed Oct 20, 2022
1 parent 160bb0e commit 8415ec8
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/go/constant/value.go
Expand Up @@ -200,7 +200,13 @@ func (x floatVal) String() string {
// Use exact fmt formatting if in float64 range (common case):
// proceed if f doesn't underflow to 0 or overflow to inf.
if x, _ := f.Float64(); f.Sign() == 0 == (x == 0) && !math.IsInf(x, 0) {
return fmt.Sprintf("%.6g", x)
s := fmt.Sprintf("%.6g", x)
if !f.IsInt() && strings.IndexByte(s, '.') < 0 {
// f is not an integer, but its string representation
// doesn't reflect that. Use more digits. See issue 56220.
s = fmt.Sprintf("%g", x)
}
return s
}

// Out of float64 range. Do approximate manual to decimal
Expand Down
15 changes: 15 additions & 0 deletions test/fixedbugs/issue56220.go
@@ -0,0 +1,15 @@
// errorcheck

// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package p

func f() int {
return int(1 - .0000001) // ERROR "cannot convert 1 - \.0000001 \(untyped float constant 0\.9999999\) to type int"
}

func g() int64 {
return int64((float64(0.03) - float64(0.02)) * 1_000_000) // ERROR "cannot convert \(float64\(0\.03\) - float64\(0\.02\)\) \* 1_000_000 \(constant 9999\.999999999998 of type float64\) to type int64"
}

0 comments on commit 8415ec8

Please sign in to comment.