Skip to content

Commit 3663a43

Browse files
committed
[dev.typeparams] go/constant: in ToFloat, convert to rational numbers, not floats
Floating-point constants are represented as rational numbers when possible (i.e., when numerators and denominators are not too large). If we convert to floats when not necessary, we risk losing precision. This is the minimal fix for the specific issue, but it's too aggressive: If the numbers are too large, we still want to convert to floats. Will address in a separate CL that also does a few related cleanups. Fixes #43908. Change-Id: Id575e34fa18361a347c43701cfb4dd7221997f66 Reviewed-on: https://go-review.googlesource.com/c/go/+/286552 Trust: Robert Griesemer <[email protected]> Run-TryBot: Robert Griesemer <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> TryBot-Result: Go Bot <[email protected]>
1 parent 3432d24 commit 3663a43

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

src/go/constant/value.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -871,9 +871,9 @@ func ToInt(x Value) Value {
871871
func ToFloat(x Value) Value {
872872
switch x := x.(type) {
873873
case int64Val:
874-
return i64tof(x)
874+
return i64tor(x)
875875
case intVal:
876-
return itof(x)
876+
return itor(x)
877877
case ratVal, floatVal:
878878
return x
879879
case complexVal:

test/fixedbugs/issue43908.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// run
2+
3+
// Copyright 2021 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
// Verify exact constant evaluation independent of
8+
// (mathematically equivalent) expression form.
9+
10+
package main
11+
12+
import "fmt"
13+
14+
const ulp1 = imag(1i + 2i / 3 - 5i / 3)
15+
const ulp2 = imag(1i + complex(0, 2) / 3 - 5i / 3)
16+
17+
func main() {
18+
if ulp1 != ulp2 {
19+
panic(fmt.Sprintf("%g != %g\n", ulp1, ulp2))
20+
}
21+
}

0 commit comments

Comments
 (0)