1// Copyright 2020 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package runtime_test
6
7import (
8	"testing"
9)
10
11var res int64
12var ures uint64
13
14func TestFloatTruncation(t *testing.T) {
15	testdata := []struct {
16		input      float64
17		convInt64  int64
18		convUInt64 uint64
19		overflow   bool
20	}{
21		// max +- 1
22		{
23			input:      0x7fffffffffffffff,
24			convInt64:  -0x8000000000000000,
25			convUInt64: 0x8000000000000000,
26		},
27		// For out-of-bounds conversion, the result is implementation-dependent.
28		// This test verifies the implementation of wasm architecture.
29		{
30			input:      0x8000000000000000,
31			convInt64:  -0x8000000000000000,
32			convUInt64: 0x8000000000000000,
33		},
34		{
35			input:      0x7ffffffffffffffe,
36			convInt64:  -0x8000000000000000,
37			convUInt64: 0x8000000000000000,
38		},
39		// neg max +- 1
40		{
41			input:      -0x8000000000000000,
42			convInt64:  -0x8000000000000000,
43			convUInt64: 0x8000000000000000,
44		},
45		{
46			input:      -0x8000000000000001,
47			convInt64:  -0x8000000000000000,
48			convUInt64: 0x8000000000000000,
49		},
50		{
51			input:      -0x7fffffffffffffff,
52			convInt64:  -0x8000000000000000,
53			convUInt64: 0x8000000000000000,
54		},
55		// trunc point +- 1
56		{
57			input:      0x7ffffffffffffdff,
58			convInt64:  0x7ffffffffffffc00,
59			convUInt64: 0x7ffffffffffffc00,
60		},
61		{
62			input:      0x7ffffffffffffe00,
63			convInt64:  -0x8000000000000000,
64			convUInt64: 0x8000000000000000,
65		},
66		{
67			input:      0x7ffffffffffffdfe,
68			convInt64:  0x7ffffffffffffc00,
69			convUInt64: 0x7ffffffffffffc00,
70		},
71		// neg trunc point +- 1
72		{
73			input:      -0x7ffffffffffffdff,
74			convInt64:  -0x7ffffffffffffc00,
75			convUInt64: 0x8000000000000000,
76		},
77		{
78			input:      -0x7ffffffffffffe00,
79			convInt64:  -0x8000000000000000,
80			convUInt64: 0x8000000000000000,
81		},
82		{
83			input:      -0x7ffffffffffffdfe,
84			convInt64:  -0x7ffffffffffffc00,
85			convUInt64: 0x8000000000000000,
86		},
87		// umax +- 1
88		{
89			input:      0xffffffffffffffff,
90			convInt64:  -0x8000000000000000,
91			convUInt64: 0x8000000000000000,
92		},
93		{
94			input:      0x10000000000000000,
95			convInt64:  -0x8000000000000000,
96			convUInt64: 0x8000000000000000,
97		},
98		{
99			input:      0xfffffffffffffffe,
100			convInt64:  -0x8000000000000000,
101			convUInt64: 0x8000000000000000,
102		},
103		// umax trunc +- 1
104		{
105			input:      0xfffffffffffffbff,
106			convInt64:  -0x8000000000000000,
107			convUInt64: 0xfffffffffffff800,
108		},
109		{
110			input:      0xfffffffffffffc00,
111			convInt64:  -0x8000000000000000,
112			convUInt64: 0x8000000000000000,
113		},
114		{
115			input:      0xfffffffffffffbfe,
116			convInt64:  -0x8000000000000000,
117			convUInt64: 0xfffffffffffff800,
118		},
119	}
120	for _, item := range testdata {
121		if got, want := int64(item.input), item.convInt64; got != want {
122			t.Errorf("int64(%f): got %x, want %x", item.input, got, want)
123		}
124		if got, want := uint64(item.input), item.convUInt64; got != want {
125			t.Errorf("uint64(%f): got %x, want %x", item.input, got, want)
126		}
127	}
128}
129