Skip to content

Commit 7dd4ae5

Browse files
jakebaileyCopilot
andauthored
Fix number conversion for Go 1.26 (#1864)
Co-authored-by: Copilot <[email protected]>
1 parent 09edcb8 commit 7dd4ae5

File tree

2 files changed

+24
-22
lines changed

2 files changed

+24
-22
lines changed

internal/jsnum/jsnum.go

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,31 +41,33 @@ func isNonFinite(x float64) bool {
4141
}
4242

4343
// https://tc39.es/ecma262/2024/multipage/abstract-operations.html#sec-touint32
44-
func (n Number) toUint32() uint32 {
44+
func (x Number) toUint32() uint32 {
45+
// The only difference between ToUint32 and ToInt32 is the interpretation of the bits.
46+
return uint32(x.toInt32())
47+
}
48+
49+
// https://tc39.es/ecma262/2024/multipage/abstract-operations.html#sec-toint32
50+
func (n Number) toInt32() int32 {
4551
x := float64(n)
46-
// Fast path: if the number is the range (-2^31, 2^32), i.e. an SMI,
52+
53+
// Fast path: if the number is in the range (-2^31, 2^32), i.e. an SMI,
4754
// then we don't need to do any special mapping.
4855
if smi := int32(x); float64(smi) == x {
49-
return uint32(smi)
56+
return smi
5057
}
5158

52-
// If the number is non-finite (NaN, +Inf, -Inf; exp=0x7FF), it maps to zero.
59+
// 2. If number is not finite or number is either +0𝔽 or -0𝔽, return +0𝔽.
60+
// Zero was covered by the test above.
5361
if isNonFinite(x) {
5462
return 0
5563
}
5664

57-
// Otherwise, take x modulo 2^32, mapping positive numbers
58-
// to [0, 2^32) and negative numbers to (-2^32, -0.0].
65+
// Let int be truncate(ℝ(number)).
66+
x = math.Trunc(x)
67+
// Let int32bit be int modulo 2**32.
5968
x = math.Mod(x, 1<<32)
60-
61-
// Convert to uint32, which will wrap negative numbers.
62-
return uint32(x)
63-
}
64-
65-
// https://tc39.es/ecma262/2024/multipage/abstract-operations.html#sec-toint32
66-
func (x Number) toInt32() int32 {
67-
// The only difference between ToUint32 and ToInt32 is the interpretation of the bits.
68-
return int32(x.toUint32())
69+
// If int32bit ≥ 2**31, return 𝔽(int32bit - 2**32); otherwise return 𝔽(int32bit).
70+
return int32(int64(x))
6971
}
7072

7173
func (x Number) toShiftCount() uint32 {

internal/jsnum/jsnum_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,18 +109,18 @@ func TestBitwiseNOT(t *testing.T) {
109109
t.Parallel()
110110

111111
tests := []struct {
112-
input, want Number
112+
got, want Number
113113
}{
114-
{-2147483649, Number(2147483647).BitwiseNOT()},
115-
{-4294967296, Number(0).BitwiseNOT()},
116-
{2147483648, Number(-2147483648).BitwiseNOT()},
117-
{4294967296, Number(0).BitwiseNOT()},
114+
{Number(-2147483649).BitwiseNOT(), Number(2147483647).BitwiseNOT()},
115+
{Number(-4294967296).BitwiseNOT(), Number(0).BitwiseNOT()},
116+
{Number(2147483648).BitwiseNOT(), Number(-2147483648).BitwiseNOT()},
117+
{Number(4294967296).BitwiseNOT(), Number(0).BitwiseNOT()},
118118
}
119119

120120
for _, test := range tests {
121-
t.Run(test.input.String(), func(t *testing.T) {
121+
t.Run(test.got.String(), func(t *testing.T) {
122122
t.Parallel()
123-
assertEqualNumber(t, test.input.BitwiseNOT(), test.want)
123+
assertEqualNumber(t, test.got, test.want)
124124
})
125125
}
126126
}

0 commit comments

Comments
 (0)