mirror of https://github.com/golang/go.git
runtime: use correct truncated constants for float conversion
There is a range of numbers lower than 0x7fff_ffff_ffff_ffff which cannot be represented by a 64 bit float. We set that to the correct limit beyond which conversions can happen properly. It appears that the negative bound check can indeed by correctly handled by I64TruncF64S. But we use the same limit for consistency. Fixes #38839 Change-Id: Ib783a22cb331fba7e6955459f41c67f9ceb53461 Reviewed-on: https://go-review.googlesource.com/c/go/+/231837 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
0f47c12a29
commit
4daf8719e7
|
|
@ -0,0 +1,128 @@
|
|||
// Copyright 2020 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 runtime_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var res int64
|
||||
var ures uint64
|
||||
|
||||
func TestFloatTruncation(t *testing.T) {
|
||||
testdata := []struct {
|
||||
input float64
|
||||
convInt64 int64
|
||||
convUInt64 uint64
|
||||
overflow bool
|
||||
}{
|
||||
// max +- 1
|
||||
{
|
||||
input: 0x7fffffffffffffff,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
// For out-of-bounds conversion, the result is implementation-dependent.
|
||||
// This test verifies the implementation of wasm architecture.
|
||||
{
|
||||
input: 0x8000000000000000,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
{
|
||||
input: 0x7ffffffffffffffe,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
// neg max +- 1
|
||||
{
|
||||
input: -0x8000000000000000,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
{
|
||||
input: -0x8000000000000001,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
{
|
||||
input: -0x7fffffffffffffff,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
// trunc point +- 1
|
||||
{
|
||||
input: 0x7ffffffffffffdff,
|
||||
convInt64: 0x7ffffffffffffc00,
|
||||
convUInt64: 0x7ffffffffffffc00,
|
||||
},
|
||||
{
|
||||
input: 0x7ffffffffffffe00,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
{
|
||||
input: 0x7ffffffffffffdfe,
|
||||
convInt64: 0x7ffffffffffffc00,
|
||||
convUInt64: 0x7ffffffffffffc00,
|
||||
},
|
||||
// neg trunc point +- 1
|
||||
{
|
||||
input: -0x7ffffffffffffdff,
|
||||
convInt64: -0x7ffffffffffffc00,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
{
|
||||
input: -0x7ffffffffffffe00,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
{
|
||||
input: -0x7ffffffffffffdfe,
|
||||
convInt64: -0x7ffffffffffffc00,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
// umax +- 1
|
||||
{
|
||||
input: 0xffffffffffffffff,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
{
|
||||
input: 0x10000000000000000,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
{
|
||||
input: 0xfffffffffffffffe,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
// umax trunc +- 1
|
||||
{
|
||||
input: 0xfffffffffffffbff,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0xfffffffffffff800,
|
||||
},
|
||||
{
|
||||
input: 0xfffffffffffffc00,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0x8000000000000000,
|
||||
},
|
||||
{
|
||||
input: 0xfffffffffffffbfe,
|
||||
convInt64: -0x8000000000000000,
|
||||
convUInt64: 0xfffffffffffff800,
|
||||
},
|
||||
}
|
||||
for _, item := range testdata {
|
||||
if got, want := int64(item.input), item.convInt64; got != want {
|
||||
t.Errorf("int64(%f): got %x, want %x", item.input, got, want)
|
||||
}
|
||||
if got, want := uint64(item.input), item.convUInt64; got != want {
|
||||
t.Errorf("uint64(%f): got %x, want %x", item.input, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ TEXT runtime·wasmTruncS(SB), NOSPLIT, $0-0
|
|||
End
|
||||
|
||||
Get R0
|
||||
F64Const $9223372036854775807.
|
||||
F64Const $0x7ffffffffffffc00p0 // Maximum truncated representation of 0x7fffffffffffffff
|
||||
F64Gt
|
||||
If
|
||||
I64Const $0x8000000000000000
|
||||
|
|
@ -107,7 +107,7 @@ TEXT runtime·wasmTruncS(SB), NOSPLIT, $0-0
|
|||
End
|
||||
|
||||
Get R0
|
||||
F64Const $-9223372036854775808.
|
||||
F64Const $-0x7ffffffffffffc00p0 // Minimum truncated representation of -0x8000000000000000
|
||||
F64Lt
|
||||
If
|
||||
I64Const $0x8000000000000000
|
||||
|
|
@ -128,7 +128,7 @@ TEXT runtime·wasmTruncU(SB), NOSPLIT, $0-0
|
|||
End
|
||||
|
||||
Get R0
|
||||
F64Const $18446744073709551615.
|
||||
F64Const $0xfffffffffffff800p0 // Maximum truncated representation of 0xffffffffffffffff
|
||||
F64Gt
|
||||
If
|
||||
I64Const $0x8000000000000000
|
||||
|
|
|
|||
Loading…
Reference in New Issue