]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: don't truncate tiny float constants to 0 in error messages
authorRobert Griesemer <gri@golang.org>
Thu, 10 Dec 2015 01:22:48 +0000 (17:22 -0800)
committerRobert Griesemer <gri@golang.org>
Thu, 10 Dec 2015 16:39:46 +0000 (16:39 +0000)
Fixes #13559.

Change-Id: I6fe8b5083192e8eb6c1b3ca1919fde81a00ccb7e
Reviewed-on: https://go-review.googlesource.com/17695
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
src/cmd/compile/internal/gc/mparith3.go
test/fixedbugs/issue11326.go
test/fixedbugs/issue11590.go
test/fixedbugs/issue13471.go
test/fixedbugs/issue13559.go [new file with mode: 0644]

index 889c461cc9e44114ed8a8893aaeb9809997de195..9bcfda7c0d7676743528a15449f4c8727f15112e 100644 (file)
@@ -212,31 +212,40 @@ func Fconv(fvp *Mpflt, flag int) string {
                return sign + "Inf"
        }
 
-       // Use fmt formatting if in float64 range (common case).
-       if x, _ := f.Float64(); !math.IsInf(x, 0) {
+       // 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("%s%.6g", sign, x)
        }
 
        // Out of float64 range. Do approximate manual to decimal
        // conversion to avoid precise but possibly slow Float
-       // formatting. The exponent is > 0 since a negative out-
-       // of-range exponent would have underflowed and led to 0.
+       // formatting.
        // f = mant * 2**exp
        var mant big.Float
-       exp := float64(f.MantExp(&mant)) // 0.5 <= mant < 1.0, exp > 0
+       exp := f.MantExp(&mant) // 0.5 <= mant < 1.0
 
        // approximate float64 mantissa m and decimal exponent d
        // f ~ m * 10**d
-       m, _ := mant.Float64()            // 0.5 <= m < 1.0
-       d := exp * (math.Ln2 / math.Ln10) // log_10(2)
+       m, _ := mant.Float64()                     // 0.5 <= m < 1.0
+       d := float64(exp) * (math.Ln2 / math.Ln10) // log_10(2)
 
        // adjust m for truncated (integer) decimal exponent e
        e := int64(d)
        m *= math.Pow(10, d-float64(e))
-       for m >= 10 {
+
+       // ensure 1 <= m < 10
+       switch {
+       case m < 1-0.5e-6:
+               // The %.6g format below rounds m to 5 digits after the
+               // decimal point. Make sure that m*10 < 10 even after
+               // rounding up: m*10 + 0.5e-5 < 10 => m < 1 - 0.5e6.
+               m *= 10
+               e--
+       case m >= 10:
                m /= 10
                e++
        }
 
-       return fmt.Sprintf("%s%.5fe+%d", sign, m, e)
+       return fmt.Sprintf("%s%.6ge%+d", sign, m, e)
 }
index 85f56a3dda182dff56cf0a6774e299a139e93990..3a4fbff3759ed7c82ca0c47745a40159c607219b 100644 (file)
@@ -18,14 +18,14 @@ func main() {
 
        // Any implementation must be able to handle these constants at
        // compile time (even though they cannot be assigned to a float64).
-       var _ = 1e646456992  // ERROR "1.00000e\+646456992 overflows float64"
-       var _ = 1e64645699   // ERROR "1.00000e\+64645699 overflows float64"
-       var _ = 1e6464569    // ERROR "1.00000e\+6464569 overflows float64"
-       var _ = 1e646456     // ERROR "1.00000e\+646456 overflows float64"
-       var _ = 1e64645      // ERROR "1.00000e\+64645 overflows float64"
-       var _ = 1e6464       // ERROR "1.00000e\+6464 overflows float64"
-       var _ = 1e646        // ERROR "1.00000e\+646 overflows float64"
-       var _ = 1e309        // ERROR "1.00000e\+309 overflows float64"
+       var _ = 1e646456992  // ERROR "1e\+646456992 overflows float64"
+       var _ = 1e64645699   // ERROR "1e\+64645699 overflows float64"
+       var _ = 1e6464569    // ERROR "1e\+6464569 overflows float64"
+       var _ = 1e646456     // ERROR "1e\+646456 overflows float64"
+       var _ = 1e64645      // ERROR "1e\+64645 overflows float64"
+       var _ = 1e6464       // ERROR "1e\+6464 overflows float64"
+       var _ = 1e646        // ERROR "1e\+646 overflows float64"
+       var _ = 1e309        // ERROR "1e\+309 overflows float64"
 
        var _ = 1e308
 }
index 1acac64c735d6f2eada994ca5570a1aaae86ef6f..f3032fcd53567f387af49ffd1b4d6e6089d7299d 100644 (file)
@@ -8,4 +8,4 @@ package p
 
 var _ = int8(4) * 300         // ERROR "constant 300 overflows int8" "constant 1200 overflows int8"
 var _ = complex64(1) * 1e200  // ERROR "constant 1e\+200 overflows complex64"
-var _ = complex128(1) * 1e500 // ERROR "constant 1\.00000e\+500 overflows complex128"
+var _ = complex128(1) * 1e500 // ERROR "constant 1e\+500 overflows complex128"
index cda668a1a5b93a92e0681bbd01edad1d1e8bd2f7..eee408105d2b10dee3ccdc56aca8b3c86343fd99 100644 (file)
@@ -9,17 +9,17 @@
 package main
 
 func main() {
-       const _ int64 = 1e646456992 // ERROR "1.00000e\+646456992 overflows integer"
-       const _ int32 = 1e64645699  // ERROR "1.00000e\+64645699 overflows integer"
-       const _ int16 = 1e6464569   // ERROR "1.00000e\+6464569 overflows integer"
-       const _ int8 = 1e646456     // ERROR "1.00000e\+646456 overflows integer"
-       const _ int = 1e64645       // ERROR "1.00000e\+64645 overflows integer"
+       const _ int64 = 1e646456992 // ERROR "1e\+646456992 overflows integer"
+       const _ int32 = 1e64645699  // ERROR "1e\+64645699 overflows integer"
+       const _ int16 = 1e6464569   // ERROR "1e\+6464569 overflows integer"
+       const _ int8 = 1e646456     // ERROR "1e\+646456 overflows integer"
+       const _ int = 1e64645       // ERROR "1e\+64645 overflows integer"
 
-       const _ uint64 = 1e646456992 // ERROR "1.00000e\+646456992 overflows integer"
-       const _ uint32 = 1e64645699  // ERROR "1.00000e\+64645699 overflows integer"
-       const _ uint16 = 1e6464569   // ERROR "1.00000e\+6464569 overflows integer"
-       const _ uint8 = 1e646456     // ERROR "1.00000e\+646456 overflows integer"
-       const _ uint = 1e64645       // ERROR "1.00000e\+64645 overflows integer"
+       const _ uint64 = 1e646456992 // ERROR "1e\+646456992 overflows integer"
+       const _ uint32 = 1e64645699  // ERROR "1e\+64645699 overflows integer"
+       const _ uint16 = 1e6464569   // ERROR "1e\+6464569 overflows integer"
+       const _ uint8 = 1e646456     // ERROR "1e\+646456 overflows integer"
+       const _ uint = 1e64645       // ERROR "1e\+64645 overflows integer"
 
-       const _ rune = 1e64645 // ERROR "1.00000e\+64645 overflows integer"
+       const _ rune = 1e64645 // ERROR "1e\+64645 overflows integer"
 }
diff --git a/test/fixedbugs/issue13559.go b/test/fixedbugs/issue13559.go
new file mode 100644 (file)
index 0000000..4783c62
--- /dev/null
@@ -0,0 +1,89 @@
+// errorcheck
+
+// Copyright 2015 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.
+
+// Verify that error messages print meaningful values
+// for various extreme floating-point constants.
+
+package p
+
+// failure case in issue
+const _ int64 = 1e-10000 // ERROR "1e\-10000 truncated"
+
+const (
+       _ int64 = 1e10000000 // ERROR "1e\+10000000 overflows"
+       _ int64 = 1e1000000  // ERROR "1e\+1000000 overflows"
+       _ int64 = 1e100000   // ERROR "1e\+100000 overflows"
+       _ int64 = 1e10000    // ERROR "1e\+10000 overflows"
+       _ int64 = 1e1000     // ERROR "1e\+1000 overflows"
+       _ int64 = 1e100      // ERROR "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows"
+       _ int64 = 1e10
+       _ int64 = 1e1
+       _ int64 = 1e0
+       _ int64 = 1e-1       // ERROR "0\.1 truncated"
+       _ int64 = 1e-10      // ERROR "1e\-10 truncated"
+       _ int64 = 1e-100     // ERROR "1e\-100 truncated"
+       _ int64 = 1e-1000    // ERROR "1e\-1000 truncated"
+       _ int64 = 1e-10000   // ERROR "1e\-10000 truncated"
+       _ int64 = 1e-100000  // ERROR "1e\-100000 truncated"
+       _ int64 = 1e-1000000 // ERROR "1e\-1000000 truncated"
+)
+
+const (
+       _ int64 = -1e10000000 // ERROR "\-1e\+10000000 overflows"
+       _ int64 = -1e1000000  // ERROR "\-1e\+1000000 overflows"
+       _ int64 = -1e100000   // ERROR "\-1e\+100000 overflows"
+       _ int64 = -1e10000    // ERROR "\-1e\+10000 overflows"
+       _ int64 = -1e1000     // ERROR "\-1e\+1000 overflows"
+       _ int64 = -1e100      // ERROR "\-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows"
+       _ int64 = -1e10
+       _ int64 = -1e1
+       _ int64 = -1e0
+       _ int64 = -1e-1       // ERROR "\-0\.1 truncated"
+       _ int64 = -1e-10      // ERROR "\-1e\-10 truncated"
+       _ int64 = -1e-100     // ERROR "\-1e\-100 truncated"
+       _ int64 = -1e-1000    // ERROR "\-1e\-1000 truncated"
+       _ int64 = -1e-10000   // ERROR "\-1e\-10000 truncated"
+       _ int64 = -1e-100000  // ERROR "\-1e\-100000 truncated"
+       _ int64 = -1e-1000000 // ERROR "\-1e\-1000000 truncated"
+)
+
+const (
+       _ int64 = 1.23456789e10000000 // ERROR "1\.23457e\+10000000 overflows"
+       _ int64 = 1.23456789e1000000  // ERROR "1\.23457e\+1000000 overflows"
+       _ int64 = 1.23456789e100000   // ERROR "1\.23457e\+100000 overflows"
+       _ int64 = 1.23456789e10000    // ERROR "1\.23457e\+10000 overflows"
+       _ int64 = 1.23456789e1000     // ERROR "1\.23457e\+1000 overflows"
+       _ int64 = 1.23456789e100      // ERROR "12345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows"
+       _ int64 = 1.23456789e10
+       _ int64 = 1.23456789e1        // ERROR "12\.3457 truncated"
+       _ int64 = 1.23456789e0        // ERROR "1\.23457 truncated"
+       _ int64 = 1.23456789e-1       // ERROR "0\.123457 truncated"
+       _ int64 = 1.23456789e-10      // ERROR "1\.23457e\-10 truncated"
+       _ int64 = 1.23456789e-100     // ERROR "1\.23457e\-100 truncated"
+       _ int64 = 1.23456789e-1000    // ERROR "1\.23457e\-1000 truncated"
+       _ int64 = 1.23456789e-10000   // ERROR "1\.23457e\-10000 truncated"
+       _ int64 = 1.23456789e-100000  // ERROR "1\.23457e\-100000 truncated"
+       _ int64 = 1.23456789e-1000000 // ERROR "1\.23457e\-1000000 truncated"
+)
+
+const (
+       _ int64 = -1.23456789e10000000 // ERROR "\-1\.23457e\+10000000 overflows"
+       _ int64 = -1.23456789e1000000  // ERROR "\-1\.23457e\+1000000 overflows"
+       _ int64 = -1.23456789e100000   // ERROR "\-1\.23457e\+100000 overflows"
+       _ int64 = -1.23456789e10000    // ERROR "\-1\.23457e\+10000 overflows"
+       _ int64 = -1.23456789e1000     // ERROR "\-1\.23457e\+1000 overflows"
+       _ int64 = -1.23456789e100      // ERROR "\-12345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows"
+       _ int64 = -1.23456789e10
+       _ int64 = -1.23456789e1        // ERROR "\-12\.3457 truncated"
+       _ int64 = -1.23456789e0        // ERROR "\-1\.23457 truncated"
+       _ int64 = -1.23456789e-1       // ERROR "\-0\.123457 truncated"
+       _ int64 = -1.23456789e-10      // ERROR "\-1\.23457e\-10 truncated"
+       _ int64 = -1.23456789e-100     // ERROR "\-1\.23457e\-100 truncated"
+       _ int64 = -1.23456789e-1000    // ERROR "\-1\.23457e\-1000 truncated"
+       _ int64 = -1.23456789e-10000   // ERROR "\-1\.23457e\-10000 truncated"
+       _ int64 = -1.23456789e-100000  // ERROR "\-1\.23457e\-100000 truncated"
+       _ int64 = -1.23456789e-1000000 // ERROR "\-1\.23457e\-1000000 truncated"
+)