From 8415ec8c98627326ffb48141c45917b9d7d0c234 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Thu, 13 Oct 2022 13:30:26 -0700 Subject: [PATCH] cmd/compile: in compiler errors, print more digits for floats close to 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 #56220 Change-Id: I7f5873af5993114a61460ef399d15316925a15a5 Reviewed-on: https://go-review.googlesource.com/c/go/+/442935 Reviewed-by: Rob Pike TryBot-Result: Gopher Robot Reviewed-by: Robert Griesemer Reviewed-by: Keith Randall Run-TryBot: Keith Randall --- src/go/constant/value.go | 8 +++++++- test/fixedbugs/issue56220.go | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 test/fixedbugs/issue56220.go diff --git a/src/go/constant/value.go b/src/go/constant/value.go index f8d03cf3756c1..ae300c7c13c91 100644 --- a/src/go/constant/value.go +++ b/src/go/constant/value.go @@ -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 diff --git a/test/fixedbugs/issue56220.go b/test/fixedbugs/issue56220.go new file mode 100644 index 0000000000000..3cb5210e894a3 --- /dev/null +++ b/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" +}