go.tools/go/types: fix float32 conversions
Pending CL 93550043. For submission after the 1.3 release. Fixes golang/go#8066. LGTM=adonovan R=adonovan CC=golang-codereviews https://golang.org/cl/95580045
This commit is contained in:
parent
95e5e90454
commit
459aaad458
|
|
@ -245,6 +245,22 @@ func Uint64Val(x Value) (uint64, bool) {
|
|||
panic(fmt.Sprintf("%v not an Int", x))
|
||||
}
|
||||
|
||||
// Float32Val is like Float64Val but for float32 instead of float64.
|
||||
func Float32Val(x Value) (float32, bool) {
|
||||
switch x := x.(type) {
|
||||
case int64Val:
|
||||
f := float32(x)
|
||||
return f, int64Val(f) == x
|
||||
case intVal:
|
||||
return new(big.Rat).SetFrac(x.val, int1).Float32()
|
||||
case floatVal:
|
||||
return x.val.Float32()
|
||||
case unknownVal:
|
||||
return 0, false
|
||||
}
|
||||
panic(fmt.Sprintf("%v not a Float", x))
|
||||
}
|
||||
|
||||
// Float64Val returns the nearest Go float64 value of x and whether the result is exact;
|
||||
// x must be numeric but not Complex, or Unknown. For values too small (too close to 0)
|
||||
// to represent as float64, Float64Val silently underflows to 0. The result sign always
|
||||
|
|
|
|||
|
|
@ -149,21 +149,14 @@ func isComparison(op token.Token) bool {
|
|||
}
|
||||
|
||||
func fitsFloat32(x exact.Value) bool {
|
||||
f, _ := exact.Float64Val(x)
|
||||
// spec: "In all non-constant conversions involving floating-point
|
||||
// or complex values, if the result type cannot represent the value
|
||||
// the conversion succeeds but the result value is implementation-
|
||||
// dependent."
|
||||
//
|
||||
// We assume that float32(f) returns an Inf if f is too large for
|
||||
// a float32, or if f is an Inf; and that it returns 0 for values
|
||||
// with too small a magnitude.
|
||||
return !math.IsInf(float64(float32(f)), 0)
|
||||
f32, _ := exact.Float32Val(x)
|
||||
f := float64(f32)
|
||||
return !math.IsInf(f, 0)
|
||||
}
|
||||
|
||||
func roundFloat32(x exact.Value) exact.Value {
|
||||
f, _ := exact.Float64Val(x)
|
||||
f = float64(float32(f))
|
||||
f32, _ := exact.Float32Val(x)
|
||||
f := float64(f32)
|
||||
if !math.IsInf(f, 0) {
|
||||
return exact.MakeFloat64(f)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,6 @@ func TestStdTest(t *testing.T) {
|
|||
testTestDir(t, filepath.Join(runtime.GOROOT(), "test"),
|
||||
"cmplxdivide.go", // also needs file cmplxdivide1.go - ignore
|
||||
"sigchld.go", // don't work on Windows; testTestDir should consult build tags
|
||||
"float_lit2.go", // TODO(gri) float32 constant conversion requires (missing) Rat.Float32
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,3 +14,10 @@ func issue7035() {
|
|||
fmt := new(T)
|
||||
_ = fmt.X
|
||||
}
|
||||
|
||||
func issue8066() {
|
||||
const (
|
||||
_ = float32(340282356779733661637539395458142568447)
|
||||
_ = float32(340282356779733661637539395458142568448 /* ERROR cannot convert */ )
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue