xref: /aosp_15_r20/external/starlark-go/starlark/testdata/int.star (revision 4947cdc739c985f6d86941e22894f5cefe7c9e9a)
1*4947cdc7SCole Faust# Tests of Starlark 'int'
2*4947cdc7SCole Faust
3*4947cdc7SCole Faustload("assert.star", "assert")
4*4947cdc7SCole Faust
5*4947cdc7SCole Faust# basic arithmetic
6*4947cdc7SCole Faustassert.eq(0 - 1, -1)
7*4947cdc7SCole Faustassert.eq(0 + 1, +1)
8*4947cdc7SCole Faustassert.eq(1 + 1, 2)
9*4947cdc7SCole Faustassert.eq(5 + 7, 12)
10*4947cdc7SCole Faustassert.eq(5 * 7, 35)
11*4947cdc7SCole Faustassert.eq(5 - 7, -2)
12*4947cdc7SCole Faust
13*4947cdc7SCole Faust# int boundaries
14*4947cdc7SCole Faustmaxint64 = (1 << 63) - 1
15*4947cdc7SCole Faustminint64 = -1 << 63
16*4947cdc7SCole Faustmaxint32 = (1 << 31) - 1
17*4947cdc7SCole Faustminint32 = -1 << 31
18*4947cdc7SCole Faustassert.eq(maxint64, 9223372036854775807)
19*4947cdc7SCole Faustassert.eq(minint64, -9223372036854775808)
20*4947cdc7SCole Faustassert.eq(maxint32, 2147483647)
21*4947cdc7SCole Faustassert.eq(minint32, -2147483648)
22*4947cdc7SCole Faust
23*4947cdc7SCole Faust# truth
24*4947cdc7SCole Faustdef truth():
25*4947cdc7SCole Faust    assert.true(not 0)
26*4947cdc7SCole Faust    for m in [1, maxint32]:  # Test small/big ranges
27*4947cdc7SCole Faust        assert.true(123 * m)
28*4947cdc7SCole Faust        assert.true(-1 * m)
29*4947cdc7SCole Faust
30*4947cdc7SCole Fausttruth()
31*4947cdc7SCole Faust
32*4947cdc7SCole Faust# floored division
33*4947cdc7SCole Faust# (For real division, see float.star.)
34*4947cdc7SCole Faustdef division():
35*4947cdc7SCole Faust    for m in [1, maxint32]:  # Test small/big ranges
36*4947cdc7SCole Faust        assert.eq((100 * m) // (7 * m), 14)
37*4947cdc7SCole Faust        assert.eq((100 * m) // (-7 * m), -15)
38*4947cdc7SCole Faust        assert.eq((-100 * m) // (7 * m), -15)  # NB: different from Go/Java
39*4947cdc7SCole Faust        assert.eq((-100 * m) // (-7 * m), 14)  # NB: different from Go/Java
40*4947cdc7SCole Faust        assert.eq((98 * m) // (7 * m), 14)
41*4947cdc7SCole Faust        assert.eq((98 * m) // (-7 * m), -14)
42*4947cdc7SCole Faust        assert.eq((-98 * m) // (7 * m), -14)
43*4947cdc7SCole Faust        assert.eq((-98 * m) // (-7 * m), 14)
44*4947cdc7SCole Faust
45*4947cdc7SCole Faustdivision()
46*4947cdc7SCole Faust
47*4947cdc7SCole Faust# remainder
48*4947cdc7SCole Faustdef remainder():
49*4947cdc7SCole Faust    for m in [1, maxint32]:  # Test small/big ranges
50*4947cdc7SCole Faust        assert.eq((100 * m) % (7 * m), 2 * m)
51*4947cdc7SCole Faust        assert.eq((100 * m) % (-7 * m), -5 * m)  # NB: different from Go/Java
52*4947cdc7SCole Faust        assert.eq((-100 * m) % (7 * m), 5 * m)  # NB: different from Go/Java
53*4947cdc7SCole Faust        assert.eq((-100 * m) % (-7 * m), -2 * m)
54*4947cdc7SCole Faust        assert.eq((98 * m) % (7 * m), 0)
55*4947cdc7SCole Faust        assert.eq((98 * m) % (-7 * m), 0)
56*4947cdc7SCole Faust        assert.eq((-98 * m) % (7 * m), 0)
57*4947cdc7SCole Faust        assert.eq((-98 * m) % (-7 * m), 0)
58*4947cdc7SCole Faust
59*4947cdc7SCole Faustremainder()
60*4947cdc7SCole Faust
61*4947cdc7SCole Faust# compound assignment
62*4947cdc7SCole Faustdef compound():
63*4947cdc7SCole Faust    x = 1
64*4947cdc7SCole Faust    x += 1
65*4947cdc7SCole Faust    assert.eq(x, 2)
66*4947cdc7SCole Faust    x -= 3
67*4947cdc7SCole Faust    assert.eq(x, -1)
68*4947cdc7SCole Faust    x *= 39
69*4947cdc7SCole Faust    assert.eq(x, -39)
70*4947cdc7SCole Faust    x //= 4
71*4947cdc7SCole Faust    assert.eq(x, -10)
72*4947cdc7SCole Faust    x /= -2
73*4947cdc7SCole Faust    assert.eq(x, 5)
74*4947cdc7SCole Faust    x %= 3
75*4947cdc7SCole Faust    assert.eq(x, 2)
76*4947cdc7SCole Faust
77*4947cdc7SCole Faust    # use resolve.AllowBitwise to enable the ops:
78*4947cdc7SCole Faust    x = 2
79*4947cdc7SCole Faust    x &= 1
80*4947cdc7SCole Faust    assert.eq(x, 0)
81*4947cdc7SCole Faust    x |= 2
82*4947cdc7SCole Faust    assert.eq(x, 2)
83*4947cdc7SCole Faust    x ^= 3
84*4947cdc7SCole Faust    assert.eq(x, 1)
85*4947cdc7SCole Faust    x <<= 2
86*4947cdc7SCole Faust    assert.eq(x, 4)
87*4947cdc7SCole Faust    x >>= 2
88*4947cdc7SCole Faust    assert.eq(x, 1)
89*4947cdc7SCole Faust
90*4947cdc7SCole Faustcompound()
91*4947cdc7SCole Faust
92*4947cdc7SCole Faust# int conversion
93*4947cdc7SCole Faust# See float.star for float-to-int conversions.
94*4947cdc7SCole Faust# We follow Python 3 here, but I can't see the method in its madness.
95*4947cdc7SCole Faust# int from bool/int/float
96*4947cdc7SCole Faustassert.fails(int, "missing argument")  # int()
97*4947cdc7SCole Faustassert.eq(int(False), 0)
98*4947cdc7SCole Faustassert.eq(int(True), 1)
99*4947cdc7SCole Faustassert.eq(int(3), 3)
100*4947cdc7SCole Faustassert.eq(int(3.1), 3)
101*4947cdc7SCole Faustassert.fails(lambda: int(3, base = 10), "non-string with explicit base")
102*4947cdc7SCole Faustassert.fails(lambda: int(True, 10), "non-string with explicit base")
103*4947cdc7SCole Faust
104*4947cdc7SCole Faust# int from string, base implicitly 10
105*4947cdc7SCole Faustassert.eq(int("100000000000000000000"), 10000000000 * 10000000000)
106*4947cdc7SCole Faustassert.eq(int("-100000000000000000000"), -10000000000 * 10000000000)
107*4947cdc7SCole Faustassert.eq(int("123"), 123)
108*4947cdc7SCole Faustassert.eq(int("-123"), -123)
109*4947cdc7SCole Faustassert.eq(int("0123"), 123)  # not octal
110*4947cdc7SCole Faustassert.eq(int("-0123"), -123)
111*4947cdc7SCole Faustassert.fails(lambda: int("0x12"), "invalid literal with base 10")
112*4947cdc7SCole Faustassert.fails(lambda: int("-0x12"), "invalid literal with base 10")
113*4947cdc7SCole Faustassert.fails(lambda: int("0o123"), "invalid literal.*base 10")
114*4947cdc7SCole Faustassert.fails(lambda: int("-0o123"), "invalid literal.*base 10")
115*4947cdc7SCole Faust
116*4947cdc7SCole Faust# int from string, explicit base
117*4947cdc7SCole Faustassert.eq(int("0"), 0)
118*4947cdc7SCole Faustassert.eq(int("00"), 0)
119*4947cdc7SCole Faustassert.eq(int("0", base = 10), 0)
120*4947cdc7SCole Faustassert.eq(int("00", base = 10), 0)
121*4947cdc7SCole Faustassert.eq(int("0", base = 8), 0)
122*4947cdc7SCole Faustassert.eq(int("00", base = 8), 0)
123*4947cdc7SCole Faustassert.eq(int("-0"), 0)
124*4947cdc7SCole Faustassert.eq(int("-00"), 0)
125*4947cdc7SCole Faustassert.eq(int("-0", base = 10), 0)
126*4947cdc7SCole Faustassert.eq(int("-00", base = 10), 0)
127*4947cdc7SCole Faustassert.eq(int("-0", base = 8), 0)
128*4947cdc7SCole Faustassert.eq(int("-00", base = 8), 0)
129*4947cdc7SCole Faustassert.eq(int("+0"), 0)
130*4947cdc7SCole Faustassert.eq(int("+00"), 0)
131*4947cdc7SCole Faustassert.eq(int("+0", base = 10), 0)
132*4947cdc7SCole Faustassert.eq(int("+00", base = 10), 0)
133*4947cdc7SCole Faustassert.eq(int("+0", base = 8), 0)
134*4947cdc7SCole Faustassert.eq(int("+00", base = 8), 0)
135*4947cdc7SCole Faustassert.eq(int("11", base = 9), 10)
136*4947cdc7SCole Faustassert.eq(int("-11", base = 9), -10)
137*4947cdc7SCole Faustassert.eq(int("10011", base = 2), 19)
138*4947cdc7SCole Faustassert.eq(int("-10011", base = 2), -19)
139*4947cdc7SCole Faustassert.eq(int("123", 8), 83)
140*4947cdc7SCole Faustassert.eq(int("-123", 8), -83)
141*4947cdc7SCole Faustassert.eq(int("0123", 8), 83)  # redundant zeros permitted
142*4947cdc7SCole Faustassert.eq(int("-0123", 8), -83)
143*4947cdc7SCole Faustassert.eq(int("00123", 8), 83)
144*4947cdc7SCole Faustassert.eq(int("-00123", 8), -83)
145*4947cdc7SCole Faustassert.eq(int("0o123", 8), 83)
146*4947cdc7SCole Faustassert.eq(int("-0o123", 8), -83)
147*4947cdc7SCole Faustassert.eq(int("123", 7), 66)  # 1*7*7 + 2*7 + 3
148*4947cdc7SCole Faustassert.eq(int("-123", 7), -66)
149*4947cdc7SCole Faustassert.eq(int("12", 16), 18)
150*4947cdc7SCole Faustassert.eq(int("-12", 16), -18)
151*4947cdc7SCole Faustassert.eq(int("0x12", 16), 18)
152*4947cdc7SCole Faustassert.eq(int("-0x12", 16), -18)
153*4947cdc7SCole Faustassert.eq(0x1000000000000001 * 0x1000000000000001, 0x1000000000000002000000000000001)
154*4947cdc7SCole Faustassert.eq(int("1010", 2), 10)
155*4947cdc7SCole Faustassert.eq(int("111111101", 2), 509)
156*4947cdc7SCole Faustassert.eq(int("0b0101", 0), 5)
157*4947cdc7SCole Faustassert.eq(int("0b0101", 2), 5) # prefix is redundant with explicit base
158*4947cdc7SCole Faustassert.eq(int("0b00000", 0), 0)
159*4947cdc7SCole Faustassert.eq(1111111111111111 * 1111111111111111, 1234567901234567654320987654321)
160*4947cdc7SCole Faustassert.fails(lambda: int("0x123", 8), "invalid literal.*base 8")
161*4947cdc7SCole Faustassert.fails(lambda: int("-0x123", 8), "invalid literal.*base 8")
162*4947cdc7SCole Faustassert.fails(lambda: int("0o123", 16), "invalid literal.*base 16")
163*4947cdc7SCole Faustassert.fails(lambda: int("-0o123", 16), "invalid literal.*base 16")
164*4947cdc7SCole Faustassert.fails(lambda: int("0x110", 2), "invalid literal.*base 2")
165*4947cdc7SCole Faust
166*4947cdc7SCole Faust# Base prefix is honored only if base=0, or if the prefix matches the explicit base.
167*4947cdc7SCole Faust# See https://github.com/google/starlark-go/issues/337
168*4947cdc7SCole Faustassert.fails(lambda: int("0b0"), "invalid literal.*base 10")
169*4947cdc7SCole Faustassert.eq(int("0b0", 0), 0)
170*4947cdc7SCole Faustassert.eq(int("0b0", 2), 0)
171*4947cdc7SCole Faustassert.eq(int("0b0", 16), 0xb0)
172*4947cdc7SCole Faustassert.eq(int("0x0b0", 16), 0xb0)
173*4947cdc7SCole Faustassert.eq(int("0x0b0", 0), 0xb0)
174*4947cdc7SCole Faustassert.eq(int("0x0b0101", 16), 0x0b0101)
175*4947cdc7SCole Faust
176*4947cdc7SCole Faust# int from string, auto detect base
177*4947cdc7SCole Faustassert.eq(int("123", 0), 123)
178*4947cdc7SCole Faustassert.eq(int("+123", 0), +123)
179*4947cdc7SCole Faustassert.eq(int("-123", 0), -123)
180*4947cdc7SCole Faustassert.eq(int("0x12", 0), 18)
181*4947cdc7SCole Faustassert.eq(int("+0x12", 0), +18)
182*4947cdc7SCole Faustassert.eq(int("-0x12", 0), -18)
183*4947cdc7SCole Faustassert.eq(int("0o123", 0), 83)
184*4947cdc7SCole Faustassert.eq(int("+0o123", 0), +83)
185*4947cdc7SCole Faustassert.eq(int("-0o123", 0), -83)
186*4947cdc7SCole Faustassert.fails(lambda: int("0123", 0), "invalid literal.*base 0")  # valid in Python 2.7
187*4947cdc7SCole Faustassert.fails(lambda: int("-0123", 0), "invalid literal.*base 0")
188*4947cdc7SCole Faust
189*4947cdc7SCole Faust# github.com/google/starlark-go/issues/108
190*4947cdc7SCole Faustassert.fails(lambda: int("0Oxa", 8), "invalid literal with base 8: 0Oxa")
191*4947cdc7SCole Faust
192*4947cdc7SCole Faust# follow-on bugs to issue 108
193*4947cdc7SCole Faustassert.fails(lambda: int("--4"), "invalid literal with base 10: --4")
194*4947cdc7SCole Faustassert.fails(lambda: int("++4"), "invalid literal with base 10: \\+\\+4")
195*4947cdc7SCole Faustassert.fails(lambda: int("+-4"), "invalid literal with base 10: \\+-4")
196*4947cdc7SCole Faustassert.fails(lambda: int("0x-4", 16), "invalid literal with base 16: 0x-4")
197*4947cdc7SCole Faust
198*4947cdc7SCole Faust# bitwise union (int|int), intersection (int&int), XOR (int^int), unary not (~int),
199*4947cdc7SCole Faust# left shift (int<<int), and right shift (int>>int).
200*4947cdc7SCole Faust# use resolve.AllowBitwise to enable the ops.
201*4947cdc7SCole Faust# TODO(adonovan): this is not yet in the Starlark spec,
202*4947cdc7SCole Faust# but there is consensus that it should be.
203*4947cdc7SCole Faustassert.eq(1 | 2, 3)
204*4947cdc7SCole Faustassert.eq(3 | 6, 7)
205*4947cdc7SCole Faustassert.eq((1 | 2) & (2 | 4), 2)
206*4947cdc7SCole Faustassert.eq(1 ^ 2, 3)
207*4947cdc7SCole Faustassert.eq(2 ^ 2, 0)
208*4947cdc7SCole Faustassert.eq(1 | 0 ^ 1, 1)  # check | and ^ operators precedence
209*4947cdc7SCole Faustassert.eq(~1, -2)
210*4947cdc7SCole Faustassert.eq(~(-2), 1)
211*4947cdc7SCole Faustassert.eq(~0, -1)
212*4947cdc7SCole Faustassert.eq(1 << 2, 4)
213*4947cdc7SCole Faustassert.eq(2 >> 1, 1)
214*4947cdc7SCole Faustassert.fails(lambda: 2 << -1, "negative shift count")
215*4947cdc7SCole Faustassert.fails(lambda: 1 << 512, "shift count too large")
216*4947cdc7SCole Faust
217*4947cdc7SCole Faust# comparisons
218*4947cdc7SCole Faust# TODO(adonovan): test: < > == != etc
219*4947cdc7SCole Faustdef comparisons():
220*4947cdc7SCole Faust    for m in [1, maxint32 / 2, maxint32]:  # Test small/big ranges
221*4947cdc7SCole Faust        assert.lt(-2 * m, -1 * m)
222*4947cdc7SCole Faust        assert.lt(-1 * m, 0 * m)
223*4947cdc7SCole Faust        assert.lt(0 * m, 1 * m)
224*4947cdc7SCole Faust        assert.lt(1 * m, 2 * m)
225*4947cdc7SCole Faust        assert.true(2 * m >= 2 * m)
226*4947cdc7SCole Faust        assert.true(2 * m > 1 * m)
227*4947cdc7SCole Faust        assert.true(1 * m >= 1 * m)
228*4947cdc7SCole Faust        assert.true(1 * m > 0 * m)
229*4947cdc7SCole Faust        assert.true(0 * m >= 0 * m)
230*4947cdc7SCole Faust        assert.true(0 * m > -1 * m)
231*4947cdc7SCole Faust        assert.true(-1 * m >= -1 * m)
232*4947cdc7SCole Faust        assert.true(-1 * m > -2 * m)
233*4947cdc7SCole Faust
234*4947cdc7SCole Faustcomparisons()
235*4947cdc7SCole Faust
236*4947cdc7SCole Faust# precision
237*4947cdc7SCole Faustassert.eq(str(maxint64), "9223372036854775807")
238*4947cdc7SCole Faustassert.eq(str(maxint64 + 1), "9223372036854775808")
239*4947cdc7SCole Faustassert.eq(str(minint64), "-9223372036854775808")
240*4947cdc7SCole Faustassert.eq(str(minint64 - 1), "-9223372036854775809")
241*4947cdc7SCole Faustassert.eq(str(minint64 * minint64), "85070591730234615865843651857942052864")
242*4947cdc7SCole Faustassert.eq(str(maxint32 + 1), "2147483648")
243*4947cdc7SCole Faustassert.eq(str(minint32 - 1), "-2147483649")
244*4947cdc7SCole Faustassert.eq(str(minint32 * minint32), "4611686018427387904")
245*4947cdc7SCole Faustassert.eq(str(minint32 | maxint32), "-1")
246*4947cdc7SCole Faustassert.eq(str(minint32 & minint32), "-2147483648")
247*4947cdc7SCole Faustassert.eq(str(minint32 ^ maxint32), "-1")
248*4947cdc7SCole Faustassert.eq(str(minint32 // -1), "2147483648")
249*4947cdc7SCole Faust
250*4947cdc7SCole Faust# string formatting
251*4947cdc7SCole Faustassert.eq("%o %x %d" % (0o755, 0xDEADBEEF, 42), "755 deadbeef 42")
252*4947cdc7SCole Faustnums = [-95, -1, 0, +1, +95]
253*4947cdc7SCole Faustassert.eq(" ".join(["%o" % x for x in nums]), "-137 -1 0 1 137")
254*4947cdc7SCole Faustassert.eq(" ".join(["%d" % x for x in nums]), "-95 -1 0 1 95")
255*4947cdc7SCole Faustassert.eq(" ".join(["%i" % x for x in nums]), "-95 -1 0 1 95")
256*4947cdc7SCole Faustassert.eq(" ".join(["%x" % x for x in nums]), "-5f -1 0 1 5f")
257*4947cdc7SCole Faustassert.eq(" ".join(["%X" % x for x in nums]), "-5F -1 0 1 5F")
258*4947cdc7SCole Faustassert.eq("%o %x %d" % (123, 123, 123), "173 7b 123")
259*4947cdc7SCole Faustassert.eq("%o %x %d" % (123.1, 123.1, 123.1), "173 7b 123")  # non-int operands are acceptable
260*4947cdc7SCole Faustassert.fails(lambda: "%d" % True, "cannot convert bool to int")
261