xref: /aosp_15_r20/external/starlark-go/starlark/int_test.go (revision 4947cdc739c985f6d86941e22894f5cefe7c9e9a)
1*4947cdc7SCole Faust// Copyright 2017 The Bazel Authors. All rights reserved.
2*4947cdc7SCole Faust// Use of this source code is governed by a BSD-style
3*4947cdc7SCole Faust// license that can be found in the LICENSE file.
4*4947cdc7SCole Faust
5*4947cdc7SCole Faustpackage starlark
6*4947cdc7SCole Faust
7*4947cdc7SCole Faustimport (
8*4947cdc7SCole Faust	"fmt"
9*4947cdc7SCole Faust	"math"
10*4947cdc7SCole Faust	"math/big"
11*4947cdc7SCole Faust	"testing"
12*4947cdc7SCole Faust)
13*4947cdc7SCole Faust
14*4947cdc7SCole Faust// TestIntOpts exercises integer arithmetic, especially at the boundaries.
15*4947cdc7SCole Faustfunc TestIntOpts(t *testing.T) {
16*4947cdc7SCole Faust	f := MakeInt64
17*4947cdc7SCole Faust	left, right := big.NewInt(math.MinInt32), big.NewInt(math.MaxInt32)
18*4947cdc7SCole Faust
19*4947cdc7SCole Faust	for i, test := range []struct {
20*4947cdc7SCole Faust		val  Int
21*4947cdc7SCole Faust		want string
22*4947cdc7SCole Faust	}{
23*4947cdc7SCole Faust		// Add
24*4947cdc7SCole Faust		{f(math.MaxInt32).Add(f(1)), "80000000"},
25*4947cdc7SCole Faust		{f(math.MinInt32).Add(f(-1)), "-80000001"},
26*4947cdc7SCole Faust		// Mul
27*4947cdc7SCole Faust		{f(math.MaxInt32).Mul(f(math.MaxInt32)), "3fffffff00000001"},
28*4947cdc7SCole Faust		{f(math.MinInt32).Mul(f(math.MinInt32)), "4000000000000000"},
29*4947cdc7SCole Faust		{f(math.MaxUint32).Mul(f(math.MaxUint32)), "fffffffe00000001"},
30*4947cdc7SCole Faust		{f(math.MinInt32).Mul(f(-1)), "80000000"},
31*4947cdc7SCole Faust		// Div
32*4947cdc7SCole Faust		{f(math.MinInt32).Div(f(-1)), "80000000"},
33*4947cdc7SCole Faust		{f(1 << 31).Div(f(2)), "40000000"},
34*4947cdc7SCole Faust		// And
35*4947cdc7SCole Faust		{f(math.MaxInt32).And(f(math.MaxInt32)), "7fffffff"},
36*4947cdc7SCole Faust		{f(math.MinInt32).And(f(math.MinInt32)), "-80000000"},
37*4947cdc7SCole Faust		{f(1 << 33).And(f(1 << 32)), "0"},
38*4947cdc7SCole Faust		// Mod
39*4947cdc7SCole Faust		{f(1 << 32).Mod(f(2)), "0"},
40*4947cdc7SCole Faust		// Or
41*4947cdc7SCole Faust		{f(1 << 32).Or(f(0)), "100000000"},
42*4947cdc7SCole Faust		{f(math.MaxInt32).Or(f(0)), "7fffffff"},
43*4947cdc7SCole Faust		{f(math.MaxUint32).Or(f(0)), "ffffffff"},
44*4947cdc7SCole Faust		{f(math.MinInt32).Or(f(math.MinInt32)), "-80000000"},
45*4947cdc7SCole Faust		// Xor
46*4947cdc7SCole Faust		{f(math.MinInt32).Xor(f(-1)), "7fffffff"},
47*4947cdc7SCole Faust		// Not
48*4947cdc7SCole Faust		{f(math.MinInt32).Not(), "7fffffff"},
49*4947cdc7SCole Faust		{f(math.MaxInt32).Not(), "-80000000"},
50*4947cdc7SCole Faust		// Shift
51*4947cdc7SCole Faust		{f(1).Lsh(31), "80000000"},
52*4947cdc7SCole Faust		{f(1).Lsh(32), "100000000"},
53*4947cdc7SCole Faust		{f(math.MaxInt32 + 1).Rsh(1), "40000000"},
54*4947cdc7SCole Faust		{f(math.MinInt32 * 2).Rsh(1), "-80000000"},
55*4947cdc7SCole Faust	} {
56*4947cdc7SCole Faust		if got := fmt.Sprintf("%x", test.val); got != test.want {
57*4947cdc7SCole Faust			t.Errorf("%d equals %s, want %s", i, got, test.want)
58*4947cdc7SCole Faust		}
59*4947cdc7SCole Faust		small, big := test.val.get()
60*4947cdc7SCole Faust		if small < math.MinInt32 || math.MaxInt32 < small {
61*4947cdc7SCole Faust			t.Errorf("expected big, %d %s", i, test.val)
62*4947cdc7SCole Faust		}
63*4947cdc7SCole Faust		if big == nil {
64*4947cdc7SCole Faust			continue
65*4947cdc7SCole Faust		}
66*4947cdc7SCole Faust		if small != 0 {
67*4947cdc7SCole Faust			t.Errorf("expected 0 small, %d %s with %d", i, test.val, small)
68*4947cdc7SCole Faust		}
69*4947cdc7SCole Faust		if big.Cmp(left) >= 0 && big.Cmp(right) <= 0 {
70*4947cdc7SCole Faust			t.Errorf("expected small, %d %s", i, test.val)
71*4947cdc7SCole Faust		}
72*4947cdc7SCole Faust	}
73*4947cdc7SCole Faust}
74*4947cdc7SCole Faust
75*4947cdc7SCole Faustfunc TestImmutabilityMakeBigInt(t *testing.T) {
76*4947cdc7SCole Faust	// use max int64 for the test
77*4947cdc7SCole Faust	expect := int64(^uint64(0) >> 1)
78*4947cdc7SCole Faust
79*4947cdc7SCole Faust	mutint := big.NewInt(expect)
80*4947cdc7SCole Faust	value := MakeBigInt(mutint)
81*4947cdc7SCole Faust	mutint.Set(big.NewInt(1))
82*4947cdc7SCole Faust
83*4947cdc7SCole Faust	got, _ := value.Int64()
84*4947cdc7SCole Faust	if got != expect {
85*4947cdc7SCole Faust		t.Errorf("expected %d, got %d", expect, got)
86*4947cdc7SCole Faust	}
87*4947cdc7SCole Faust}
88*4947cdc7SCole Faust
89*4947cdc7SCole Faustfunc TestImmutabilityBigInt(t *testing.T) {
90*4947cdc7SCole Faust	// use 1 and max int64 for the test
91*4947cdc7SCole Faust	for _, expect := range []int64{1, int64(^uint64(0) >> 1)} {
92*4947cdc7SCole Faust		value := MakeBigInt(big.NewInt(expect))
93*4947cdc7SCole Faust
94*4947cdc7SCole Faust		bigint := value.BigInt()
95*4947cdc7SCole Faust		bigint.Set(big.NewInt(2))
96*4947cdc7SCole Faust
97*4947cdc7SCole Faust		got, _ := value.Int64()
98*4947cdc7SCole Faust		if got != expect {
99*4947cdc7SCole Faust			t.Errorf("expected %d, got %d", expect, got)
100*4947cdc7SCole Faust		}
101*4947cdc7SCole Faust	}
102*4947cdc7SCole Faust}
103