xref: /aosp_15_r20/external/starlark-go/starlark/testdata/float.star (revision 4947cdc739c985f6d86941e22894f5cefe7c9e9a)
1*4947cdc7SCole Faust# Tests of Starlark 'float'
2*4947cdc7SCole Faust# option:set
3*4947cdc7SCole Faust
4*4947cdc7SCole Faustload("assert.star", "assert")
5*4947cdc7SCole Faust
6*4947cdc7SCole Faust# TODO(adonovan): more tests:
7*4947cdc7SCole Faust# - precision
8*4947cdc7SCole Faust# - limits
9*4947cdc7SCole Faust
10*4947cdc7SCole Faust# type
11*4947cdc7SCole Faustassert.eq(type(0.0), "float")
12*4947cdc7SCole Faust
13*4947cdc7SCole Faust# truth
14*4947cdc7SCole Faustassert.true(123.0)
15*4947cdc7SCole Faustassert.true(-1.0)
16*4947cdc7SCole Faustassert.true(not 0.0)
17*4947cdc7SCole Faustassert.true(-1.0e-45)
18*4947cdc7SCole Faustassert.true(float("NaN"))
19*4947cdc7SCole Faust
20*4947cdc7SCole Faust# not iterable
21*4947cdc7SCole Faustassert.fails(lambda: len(0.0), 'has no len')
22*4947cdc7SCole Faustassert.fails(lambda: [x for x in 0.0], 'float value is not iterable')
23*4947cdc7SCole Faust
24*4947cdc7SCole Faust# literals
25*4947cdc7SCole Faustassert.eq(type(1.234), "float")
26*4947cdc7SCole Faustassert.eq(type(1e10), "float")
27*4947cdc7SCole Faustassert.eq(type(1e+10), "float")
28*4947cdc7SCole Faustassert.eq(type(1e-10), "float")
29*4947cdc7SCole Faustassert.eq(type(1.234e10), "float")
30*4947cdc7SCole Faustassert.eq(type(1.234e+10), "float")
31*4947cdc7SCole Faustassert.eq(type(1.234e-10), "float")
32*4947cdc7SCole Faust
33*4947cdc7SCole Faust# int/float equality
34*4947cdc7SCole Faustassert.eq(0.0, 0)
35*4947cdc7SCole Faustassert.eq(0, 0.0)
36*4947cdc7SCole Faustassert.eq(1.0, 1)
37*4947cdc7SCole Faustassert.eq(1, 1.0)
38*4947cdc7SCole Faustassert.true(1.23e45 != 1229999999999999973814869011019624571608236031)
39*4947cdc7SCole Faustassert.true(1.23e45 == 1229999999999999973814869011019624571608236032)
40*4947cdc7SCole Faustassert.true(1.23e45 != 1229999999999999973814869011019624571608236033)
41*4947cdc7SCole Faustassert.true(1229999999999999973814869011019624571608236031 != 1.23e45)
42*4947cdc7SCole Faustassert.true(1229999999999999973814869011019624571608236032 == 1.23e45)
43*4947cdc7SCole Faustassert.true(1229999999999999973814869011019624571608236033 != 1.23e45)
44*4947cdc7SCole Faust
45*4947cdc7SCole Faust# loss of precision
46*4947cdc7SCole Faustp53 = 1<<53
47*4947cdc7SCole Faustassert.eq(float(p53-1), p53-1)
48*4947cdc7SCole Faustassert.eq(float(p53+0), p53+0)
49*4947cdc7SCole Faustassert.eq(float(p53+1), p53+0) #
50*4947cdc7SCole Faustassert.eq(float(p53+2), p53+2)
51*4947cdc7SCole Faustassert.eq(float(p53+3), p53+4) #
52*4947cdc7SCole Faustassert.eq(float(p53+4), p53+4)
53*4947cdc7SCole Faustassert.eq(float(p53+5), p53+4) #
54*4947cdc7SCole Faustassert.eq(float(p53+6), p53+6)
55*4947cdc7SCole Faustassert.eq(float(p53+7), p53+8) #
56*4947cdc7SCole Faustassert.eq(float(p53+8), p53+8)
57*4947cdc7SCole Faust
58*4947cdc7SCole Faustassert.true(float(p53+1) != p53+1) # comparisons are exact
59*4947cdc7SCole Faustassert.eq(float(p53+1) - (p53+1), 0) # arithmetic entails rounding
60*4947cdc7SCole Faust
61*4947cdc7SCole Faustassert.fails(lambda: {123.0: "f", 123: "i"}, "duplicate key: 123")
62*4947cdc7SCole Faust
63*4947cdc7SCole Faust# equal int/float values have same hash
64*4947cdc7SCole Faustd = {123.0: "x"}
65*4947cdc7SCole Faustd[123] = "y"
66*4947cdc7SCole Faustassert.eq(len(d), 1)
67*4947cdc7SCole Faustassert.eq(d[123.0], "y")
68*4947cdc7SCole Faust
69*4947cdc7SCole Faust# literals (mostly covered by scanner tests)
70*4947cdc7SCole Faustassert.eq(str(0.), "0.0")
71*4947cdc7SCole Faustassert.eq(str(.0), "0.0")
72*4947cdc7SCole Faustassert.true(5.0 != 4.999999999999999)
73*4947cdc7SCole Faustassert.eq(5.0, 4.9999999999999999) # both literals denote 5.0
74*4947cdc7SCole Faustassert.eq(1.23e45, 1.23 * 1000000000000000000000000000000000000000000000)
75*4947cdc7SCole Faustassert.eq(str(1.23e-45 - (1.23 / 1000000000000000000000000000000000000000000000)), "-1.5557538194652854e-61")
76*4947cdc7SCole Faust
77*4947cdc7SCole Faustnan = float("NaN")
78*4947cdc7SCole Faustinf = float("+Inf")
79*4947cdc7SCole Faustneginf = float("-Inf")
80*4947cdc7SCole Faustnegzero = (-1e-323 / 10)
81*4947cdc7SCole Faust
82*4947cdc7SCole Faust# -- arithmetic --
83*4947cdc7SCole Faust
84*4947cdc7SCole Faust# +float, -float
85*4947cdc7SCole Faustassert.eq(+(123.0), 123.0)
86*4947cdc7SCole Faustassert.eq(-(123.0), -123.0)
87*4947cdc7SCole Faustassert.eq(-(-(123.0)), 123.0)
88*4947cdc7SCole Faustassert.eq(+(inf), inf)
89*4947cdc7SCole Faustassert.eq(-(inf), neginf)
90*4947cdc7SCole Faustassert.eq(-(neginf), inf)
91*4947cdc7SCole Faustassert.eq(str(-(nan)), "nan")
92*4947cdc7SCole Faust# +
93*4947cdc7SCole Faustassert.eq(1.2e3 + 5.6e7, 5.60012e+07)
94*4947cdc7SCole Faustassert.eq(1.2e3 + 1, 1201)
95*4947cdc7SCole Faustassert.eq(1 + 1.2e3, 1201)
96*4947cdc7SCole Faustassert.eq(str(1.2e3 + nan), "nan")
97*4947cdc7SCole Faustassert.eq(inf + 0, inf)
98*4947cdc7SCole Faustassert.eq(inf + 1, inf)
99*4947cdc7SCole Faustassert.eq(inf + inf, inf)
100*4947cdc7SCole Faustassert.eq(str(inf + neginf), "nan")
101*4947cdc7SCole Faust# -
102*4947cdc7SCole Faustassert.eq(1.2e3 - 5.6e7, -5.59988e+07)
103*4947cdc7SCole Faustassert.eq(1.2e3 - 1, 1199)
104*4947cdc7SCole Faustassert.eq(1 - 1.2e3, -1199)
105*4947cdc7SCole Faustassert.eq(str(1.2e3 - nan), "nan")
106*4947cdc7SCole Faustassert.eq(inf - 0, inf)
107*4947cdc7SCole Faustassert.eq(inf - 1, inf)
108*4947cdc7SCole Faustassert.eq(str(inf - inf), "nan")
109*4947cdc7SCole Faustassert.eq(inf - neginf, inf)
110*4947cdc7SCole Faust# *
111*4947cdc7SCole Faustassert.eq(1.5e6 * 2.2e3, 3.3e9)
112*4947cdc7SCole Faustassert.eq(1.5e6 * 123, 1.845e+08)
113*4947cdc7SCole Faustassert.eq(123 * 1.5e6, 1.845e+08)
114*4947cdc7SCole Faustassert.eq(str(1.2e3 * nan), "nan")
115*4947cdc7SCole Faustassert.eq(str(inf * 0), "nan")
116*4947cdc7SCole Faustassert.eq(inf * 1, inf)
117*4947cdc7SCole Faustassert.eq(inf * inf, inf)
118*4947cdc7SCole Faustassert.eq(inf * neginf, neginf)
119*4947cdc7SCole Faust# %
120*4947cdc7SCole Faustassert.eq(100.0 % 7.0, 2)
121*4947cdc7SCole Faustassert.eq(100.0 % -7.0, -5) # NB: different from Go / Java
122*4947cdc7SCole Faustassert.eq(-100.0 % 7.0, 5) # NB: different from Go / Java
123*4947cdc7SCole Faustassert.eq(-100.0 % -7.0, -2)
124*4947cdc7SCole Faustassert.eq(-100.0 % 7, 5)
125*4947cdc7SCole Faustassert.eq(100 % 7.0, 2)
126*4947cdc7SCole Faustassert.eq(str(1.2e3 % nan), "nan")
127*4947cdc7SCole Faustassert.eq(str(inf % 1), "nan")
128*4947cdc7SCole Faustassert.eq(str(inf % inf), "nan")
129*4947cdc7SCole Faustassert.eq(str(inf % neginf), "nan")
130*4947cdc7SCole Faust# /
131*4947cdc7SCole Faustassert.eq(str(100.0 / 7.0), "14.285714285714286")
132*4947cdc7SCole Faustassert.eq(str(100 / 7.0), "14.285714285714286")
133*4947cdc7SCole Faustassert.eq(str(100.0 / 7), "14.285714285714286")
134*4947cdc7SCole Faustassert.eq(str(100.0 / nan), "nan")
135*4947cdc7SCole Faust# //
136*4947cdc7SCole Faustassert.eq(100.0 // 7.0, 14)
137*4947cdc7SCole Faustassert.eq(100 // 7.0, 14)
138*4947cdc7SCole Faustassert.eq(100.0 // 7, 14)
139*4947cdc7SCole Faustassert.eq(100.0 // -7.0, -15)
140*4947cdc7SCole Faustassert.eq(100 // -7.0, -15)
141*4947cdc7SCole Faustassert.eq(100.0 // -7, -15)
142*4947cdc7SCole Faustassert.eq(str(1 // neginf), "-0.0")
143*4947cdc7SCole Faustassert.eq(str(100.0 // nan), "nan")
144*4947cdc7SCole Faust
145*4947cdc7SCole Faust# addition
146*4947cdc7SCole Faustassert.eq(0.0 + 1.0, 1.0)
147*4947cdc7SCole Faustassert.eq(1.0 + 1.0, 2.0)
148*4947cdc7SCole Faustassert.eq(1.25 + 2.75, 4.0)
149*4947cdc7SCole Faustassert.eq(5.0 + 7.0, 12.0)
150*4947cdc7SCole Faustassert.eq(5.1 + 7, 12.1)  # float + int
151*4947cdc7SCole Faustassert.eq(7 + 5.1, 12.1)  # int + float
152*4947cdc7SCole Faust
153*4947cdc7SCole Faust# subtraction
154*4947cdc7SCole Faustassert.eq(5.0 - 7.0, -2.0)
155*4947cdc7SCole Faustassert.eq(5.1 - 7.1, -2.0)
156*4947cdc7SCole Faustassert.eq(5.5 - 7, -1.5)
157*4947cdc7SCole Faustassert.eq(5 - 7.5, -2.5)
158*4947cdc7SCole Faustassert.eq(0.0 - 1.0, -1.0)
159*4947cdc7SCole Faust
160*4947cdc7SCole Faust# multiplication
161*4947cdc7SCole Faustassert.eq(5.0 * 7.0, 35.0)
162*4947cdc7SCole Faustassert.eq(5.5 * 2.5, 13.75)
163*4947cdc7SCole Faustassert.eq(5.5 * 7, 38.5)
164*4947cdc7SCole Faustassert.eq(5 * 7.1, 35.5)
165*4947cdc7SCole Faust
166*4947cdc7SCole Faust# real division (like Python 3)
167*4947cdc7SCole Faust# The / operator is available only when the 'fp' dialect option is enabled.
168*4947cdc7SCole Faustassert.eq(100.0 / 8.0, 12.5)
169*4947cdc7SCole Faustassert.eq(100.0 / -8.0, -12.5)
170*4947cdc7SCole Faustassert.eq(-100.0 / 8.0, -12.5)
171*4947cdc7SCole Faustassert.eq(-100.0 / -8.0, 12.5)
172*4947cdc7SCole Faustassert.eq(98.0 / 8.0, 12.25)
173*4947cdc7SCole Faustassert.eq(98.0 / -8.0, -12.25)
174*4947cdc7SCole Faustassert.eq(-98.0 / 8.0, -12.25)
175*4947cdc7SCole Faustassert.eq(-98.0 / -8.0, 12.25)
176*4947cdc7SCole Faustassert.eq(2.5 / 2.0, 1.25)
177*4947cdc7SCole Faustassert.eq(2.5 / 2, 1.25)
178*4947cdc7SCole Faustassert.eq(5 / 4.0, 1.25)
179*4947cdc7SCole Faustassert.eq(5 / 4, 1.25)
180*4947cdc7SCole Faustassert.fails(lambda: 1.0 / 0, "floating-point division by zero")
181*4947cdc7SCole Faustassert.fails(lambda: 1.0 / 0.0, "floating-point division by zero")
182*4947cdc7SCole Faustassert.fails(lambda: 1 / 0.0, "floating-point division by zero")
183*4947cdc7SCole Faust
184*4947cdc7SCole Faust# floored division
185*4947cdc7SCole Faustassert.eq(100.0 // 8.0, 12.0)
186*4947cdc7SCole Faustassert.eq(100.0 // -8.0, -13.0)
187*4947cdc7SCole Faustassert.eq(-100.0 // 8.0, -13.0)
188*4947cdc7SCole Faustassert.eq(-100.0 // -8.0, 12.0)
189*4947cdc7SCole Faustassert.eq(98.0 // 8.0, 12.0)
190*4947cdc7SCole Faustassert.eq(98.0 // -8.0, -13.0)
191*4947cdc7SCole Faustassert.eq(-98.0 // 8.0, -13.0)
192*4947cdc7SCole Faustassert.eq(-98.0 // -8.0, 12.0)
193*4947cdc7SCole Faustassert.eq(2.5 // 2.0, 1.0)
194*4947cdc7SCole Faustassert.eq(2.5 // 2, 1.0)
195*4947cdc7SCole Faustassert.eq(5 // 4.0, 1.0)
196*4947cdc7SCole Faustassert.eq(5 // 4, 1)
197*4947cdc7SCole Faustassert.eq(type(5 // 4), "int")
198*4947cdc7SCole Faustassert.fails(lambda: 1.0 // 0, "floored division by zero")
199*4947cdc7SCole Faustassert.fails(lambda: 1.0 // 0.0, "floored division by zero")
200*4947cdc7SCole Faustassert.fails(lambda: 1 // 0.0, "floored division by zero")
201*4947cdc7SCole Faust
202*4947cdc7SCole Faust# remainder
203*4947cdc7SCole Faustassert.eq(100.0 % 8.0, 4.0)
204*4947cdc7SCole Faustassert.eq(100.0 % -8.0, -4.0)
205*4947cdc7SCole Faustassert.eq(-100.0 % 8.0, 4.0)
206*4947cdc7SCole Faustassert.eq(-100.0 % -8.0, -4.0)
207*4947cdc7SCole Faustassert.eq(98.0 % 8.0, 2.0)
208*4947cdc7SCole Faustassert.eq(98.0 % -8.0, -6.0)
209*4947cdc7SCole Faustassert.eq(-98.0 % 8.0, 6.0)
210*4947cdc7SCole Faustassert.eq(-98.0 % -8.0, -2.0)
211*4947cdc7SCole Faustassert.eq(2.5 % 2.0, 0.5)
212*4947cdc7SCole Faustassert.eq(2.5 % 2, 0.5)
213*4947cdc7SCole Faustassert.eq(5 % 4.0, 1.0)
214*4947cdc7SCole Faustassert.fails(lambda: 1.0 % 0, "floating-point modulo by zero")
215*4947cdc7SCole Faustassert.fails(lambda: 1.0 % 0.0, "floating-point modulo by zero")
216*4947cdc7SCole Faustassert.fails(lambda: 1 % 0.0, "floating-point modulo by zero")
217*4947cdc7SCole Faust
218*4947cdc7SCole Faust# floats cannot be used as indices, even if integral
219*4947cdc7SCole Faustassert.fails(lambda: "abc"[1.0], "want int")
220*4947cdc7SCole Faustassert.fails(lambda: ["A", "B", "C"].insert(1.0, "D"), "want int")
221*4947cdc7SCole Faustassert.fails(lambda: range(3)[1.0], "got float, want int")
222*4947cdc7SCole Faust
223*4947cdc7SCole Faust# -- comparisons --
224*4947cdc7SCole Faust# NaN
225*4947cdc7SCole Faustassert.true(nan == nan) # \
226*4947cdc7SCole Faustassert.true(nan >= nan) #  unlike Python
227*4947cdc7SCole Faustassert.true(nan <= nan) # /
228*4947cdc7SCole Faustassert.true(not (nan > nan))
229*4947cdc7SCole Faustassert.true(not (nan < nan))
230*4947cdc7SCole Faustassert.true(not (nan != nan)) # unlike Python
231*4947cdc7SCole Faust# Sort is stable: 0.0 and -0.0 are equal, but they are not permuted.
232*4947cdc7SCole Faust# Similarly 1 and 1.0.
233*4947cdc7SCole Faustassert.eq(
234*4947cdc7SCole Faust    str(sorted([inf, neginf, nan, 1e300, -1e300, 1.0, -1.0, 1, -1, 1e-300, -1e-300, 0, 0.0, negzero, 1e-300, -1e-300])),
235*4947cdc7SCole Faust    "[-inf, -1e+300, -1.0, -1, -1e-300, -1e-300, 0, 0.0, -0.0, 1e-300, 1e-300, 1.0, 1, 1e+300, +inf, nan]")
236*4947cdc7SCole Faust
237*4947cdc7SCole Faust# Sort is stable, and its result contains no adjacent x, y such that y > x.
238*4947cdc7SCole Faust# Note: Python's reverse sort is unstable; see https://bugs.python.org/issue36095.
239*4947cdc7SCole Faustassert.eq(str(sorted([7, 3, nan, 1, 9])), "[1, 3, 7, 9, nan]")
240*4947cdc7SCole Faustassert.eq(str(sorted([7, 3, nan, 1, 9], reverse=True)), "[nan, 9, 7, 3, 1]")
241*4947cdc7SCole Faust
242*4947cdc7SCole Faust# All NaN values compare equal. (Identical objects compare equal.)
243*4947cdc7SCole Faustnandict = {nan: 1}
244*4947cdc7SCole Faustnandict[nan] = 2
245*4947cdc7SCole Faustassert.eq(len(nandict), 1) # (same as Python)
246*4947cdc7SCole Faustassert.eq(nandict[nan], 2) # (same as Python)
247*4947cdc7SCole Faustassert.fails(lambda: {nan: 1, nan: 2}, "duplicate key: nan")
248*4947cdc7SCole Faust
249*4947cdc7SCole Faustnandict[float('nan')] = 3 # a distinct NaN object
250*4947cdc7SCole Faustassert.eq(str(nandict), "{nan: 3}") # (Python: {nan: 2, nan: 3})
251*4947cdc7SCole Faust
252*4947cdc7SCole Faustassert.eq(str({inf: 1, neginf: 2}), "{+inf: 1, -inf: 2}")
253*4947cdc7SCole Faust
254*4947cdc7SCole Faust# zero
255*4947cdc7SCole Faustassert.eq(0.0, negzero)
256*4947cdc7SCole Faust
257*4947cdc7SCole Faust# inf
258*4947cdc7SCole Faustassert.eq(+inf / +inf, nan)
259*4947cdc7SCole Faustassert.eq(+inf / -inf, nan)
260*4947cdc7SCole Faustassert.eq(-inf / +inf, nan)
261*4947cdc7SCole Faustassert.eq(0.0 / +inf, 0.0)
262*4947cdc7SCole Faustassert.eq(0.0 / -inf, 0.0)
263*4947cdc7SCole Faustassert.true(inf > -inf)
264*4947cdc7SCole Faustassert.eq(inf, -neginf)
265*4947cdc7SCole Faust# TODO(adonovan): assert inf > any finite number, etc.
266*4947cdc7SCole Faust
267*4947cdc7SCole Faust# negative zero
268*4947cdc7SCole Faustnegz = -0
269*4947cdc7SCole Faustassert.eq(negz, 0)
270*4947cdc7SCole Faust
271*4947cdc7SCole Faust# min/max ordering with NaN (the greatest float value)
272*4947cdc7SCole Faustassert.eq(max([1, nan, 3]), nan)
273*4947cdc7SCole Faustassert.eq(max([nan, 2, 3]), nan)
274*4947cdc7SCole Faustassert.eq(min([1, nan, 3]), 1)
275*4947cdc7SCole Faustassert.eq(min([nan, 2, 3]), 2)
276*4947cdc7SCole Faust
277*4947cdc7SCole Faust# float/float comparisons
278*4947cdc7SCole Faustfltmax = 1.7976931348623157e+308 # approx
279*4947cdc7SCole Faustfltmin = 4.9406564584124654e-324 # approx
280*4947cdc7SCole Faustassert.lt(-inf, -fltmax)
281*4947cdc7SCole Faustassert.lt(-fltmax, -1.0)
282*4947cdc7SCole Faustassert.lt(-1.0, -fltmin)
283*4947cdc7SCole Faustassert.lt(-fltmin, 0.0)
284*4947cdc7SCole Faustassert.lt(0, fltmin)
285*4947cdc7SCole Faustassert.lt(fltmin, 1.0)
286*4947cdc7SCole Faustassert.lt(1.0, fltmax)
287*4947cdc7SCole Faustassert.lt(fltmax, inf)
288*4947cdc7SCole Faust
289*4947cdc7SCole Faust# int/float comparisons
290*4947cdc7SCole Faustassert.eq(0, 0.0)
291*4947cdc7SCole Faustassert.eq(1, 1.0)
292*4947cdc7SCole Faustassert.eq(-1, -1.0)
293*4947cdc7SCole Faustassert.ne(-1, -1.0 + 1e-7)
294*4947cdc7SCole Faustassert.lt(-2, -2 + 1e-15)
295*4947cdc7SCole Faust
296*4947cdc7SCole Faust# int conversion (rounds towards zero)
297*4947cdc7SCole Faustassert.eq(int(100.1), 100)
298*4947cdc7SCole Faustassert.eq(int(100.0), 100)
299*4947cdc7SCole Faustassert.eq(int(99.9), 99)
300*4947cdc7SCole Faustassert.eq(int(-99.9), -99)
301*4947cdc7SCole Faustassert.eq(int(-100.0), -100)
302*4947cdc7SCole Faustassert.eq(int(-100.1), -100)
303*4947cdc7SCole Faustassert.eq(int(1e100), int("10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104"))
304*4947cdc7SCole Faustassert.fails(lambda: int(inf), "cannot convert.*infinity")
305*4947cdc7SCole Faustassert.fails(lambda: int(nan), "cannot convert.*NaN")
306*4947cdc7SCole Faust
307*4947cdc7SCole Faust# -- float() function --
308*4947cdc7SCole Faustassert.eq(float(), 0.0)
309*4947cdc7SCole Faust# float(bool)
310*4947cdc7SCole Faustassert.eq(float(False), 0.0)
311*4947cdc7SCole Faustassert.eq(float(True), 1.0)
312*4947cdc7SCole Faust# float(int)
313*4947cdc7SCole Faustassert.eq(float(0), 0.0)
314*4947cdc7SCole Faustassert.eq(float(1), 1.0)
315*4947cdc7SCole Faustassert.eq(float(123), 123.0)
316*4947cdc7SCole Faustassert.eq(float(123 * 1000000 * 1000000 * 1000000 * 1000000 * 1000000), 1.23e+32)
317*4947cdc7SCole Faust# float(float)
318*4947cdc7SCole Faustassert.eq(float(1.1), 1.1)
319*4947cdc7SCole Faustassert.fails(lambda: float(None), "want number or string")
320*4947cdc7SCole Faustassert.ne(False, 0.0) # differs from Python
321*4947cdc7SCole Faustassert.ne(True, 1.0)
322*4947cdc7SCole Faust# float(string)
323*4947cdc7SCole Faustassert.eq(float("1.1"), 1.1)
324*4947cdc7SCole Faustassert.fails(lambda: float("1.1abc"), "invalid float literal")
325*4947cdc7SCole Faustassert.fails(lambda: float("1e100.0"), "invalid float literal")
326*4947cdc7SCole Faustassert.fails(lambda: float("1e1000"), "floating-point number too large")
327*4947cdc7SCole Faustassert.eq(float("-1.1"), -1.1)
328*4947cdc7SCole Faustassert.eq(float("+1.1"), +1.1)
329*4947cdc7SCole Faustassert.eq(float("+Inf"), inf)
330*4947cdc7SCole Faustassert.eq(float("-Inf"), neginf)
331*4947cdc7SCole Faustassert.eq(float("NaN"), nan)
332*4947cdc7SCole Faustassert.eq(float("NaN"), nan)
333*4947cdc7SCole Faustassert.eq(float("+NAN"), nan)
334*4947cdc7SCole Faustassert.eq(float("-nan"), nan)
335*4947cdc7SCole Faustassert.eq(str(float("Inf")), "+inf")
336*4947cdc7SCole Faustassert.eq(str(float("+INF")), "+inf")
337*4947cdc7SCole Faustassert.eq(str(float("-inf")), "-inf")
338*4947cdc7SCole Faustassert.eq(str(float("+InFiniTy")), "+inf")
339*4947cdc7SCole Faustassert.eq(str(float("-iNFiniTy")), "-inf")
340*4947cdc7SCole Faustassert.fails(lambda: float("one point two"), "invalid float literal: one point two")
341*4947cdc7SCole Faustassert.fails(lambda: float("1.2.3"), "invalid float literal: 1.2.3")
342*4947cdc7SCole Faustassert.fails(lambda: float(123 << 500 << 500 << 50), "int too large to convert to float")
343*4947cdc7SCole Faustassert.fails(lambda: float(-123 << 500 << 500 << 50), "int too large to convert to float")
344*4947cdc7SCole Faustassert.fails(lambda: float(str(-123 << 500 << 500 << 50)), "floating-point number too large")
345*4947cdc7SCole Faust
346*4947cdc7SCole Faust# -- implicit float(int) conversions --
347*4947cdc7SCole Faustassert.fails(lambda: (1<<500<<500<<500) + 0.0, "int too large to convert to float")
348*4947cdc7SCole Faustassert.fails(lambda: 0.0 + (1<<500<<500<<500), "int too large to convert to float")
349*4947cdc7SCole Faustassert.fails(lambda: (1<<500<<500<<500) - 0.0, "int too large to convert to float")
350*4947cdc7SCole Faustassert.fails(lambda: 0.0 - (1<<500<<500<<500), "int too large to convert to float")
351*4947cdc7SCole Faustassert.fails(lambda: (1<<500<<500<<500) * 1.0, "int too large to convert to float")
352*4947cdc7SCole Faustassert.fails(lambda: 1.0 * (1<<500<<500<<500), "int too large to convert to float")
353*4947cdc7SCole Faustassert.fails(lambda: (1<<500<<500<<500) / 1.0, "int too large to convert to float")
354*4947cdc7SCole Faustassert.fails(lambda: 1.0 / (1<<500<<500<<500), "int too large to convert to float")
355*4947cdc7SCole Faustassert.fails(lambda: (1<<500<<500<<500) // 1.0, "int too large to convert to float")
356*4947cdc7SCole Faustassert.fails(lambda: 1.0 // (1<<500<<500<<500), "int too large to convert to float")
357*4947cdc7SCole Faustassert.fails(lambda: (1<<500<<500<<500) % 1.0, "int too large to convert to float")
358*4947cdc7SCole Faustassert.fails(lambda: 1.0 % (1<<500<<500<<500), "int too large to convert to float")
359*4947cdc7SCole Faust
360*4947cdc7SCole Faust
361*4947cdc7SCole Faust# -- int function --
362*4947cdc7SCole Faustassert.eq(int(0.0), 0)
363*4947cdc7SCole Faustassert.eq(int(1.0), 1)
364*4947cdc7SCole Faustassert.eq(int(1.1), 1)
365*4947cdc7SCole Faustassert.eq(int(0.9), 0)
366*4947cdc7SCole Faustassert.eq(int(-1.1), -1.0)
367*4947cdc7SCole Faustassert.eq(int(-1.0), -1.0)
368*4947cdc7SCole Faustassert.eq(int(-0.9), 0.0)
369*4947cdc7SCole Faustassert.eq(int(1.23e+32), 123000000000000004979083645550592)
370*4947cdc7SCole Faustassert.eq(int(-1.23e-32), 0)
371*4947cdc7SCole Faustassert.eq(int(1.23e-32), 0)
372*4947cdc7SCole Faustassert.fails(lambda: int(float("+Inf")), "cannot convert float infinity to integer")
373*4947cdc7SCole Faustassert.fails(lambda: int(float("-Inf")), "cannot convert float infinity to integer")
374*4947cdc7SCole Faustassert.fails(lambda: int(float("NaN")), "cannot convert float NaN to integer")
375*4947cdc7SCole Faust
376*4947cdc7SCole Faust
377*4947cdc7SCole Faust# hash
378*4947cdc7SCole Faust# Check that equal float and int values have the same internal hash.
379*4947cdc7SCole Faustdef checkhash():
380*4947cdc7SCole Faust  for a in [1.23e100, 1.23e10, 1.23e1, 1.23,
381*4947cdc7SCole Faust            1, 4294967295, 8589934591, 9223372036854775807]:
382*4947cdc7SCole Faust    for b in [a, -a, 1/a, -1/a]:
383*4947cdc7SCole Faust      f = float(b)
384*4947cdc7SCole Faust      i = int(b)
385*4947cdc7SCole Faust      if f == i:
386*4947cdc7SCole Faust        fh = {f: None}
387*4947cdc7SCole Faust        ih = {i: None}
388*4947cdc7SCole Faust        if fh != ih:
389*4947cdc7SCole Faust          assert.true(False, "{%v: None} != {%v: None}: hashes vary" % fh, ih)
390*4947cdc7SCole Faustcheckhash()
391*4947cdc7SCole Faust
392*4947cdc7SCole Faust# string formatting
393*4947cdc7SCole Faust
394*4947cdc7SCole Faust# %d
395*4947cdc7SCole Faustassert.eq("%d" % 0, "0")
396*4947cdc7SCole Faustassert.eq("%d" % 0.0, "0")
397*4947cdc7SCole Faustassert.eq("%d" % 123, "123")
398*4947cdc7SCole Faustassert.eq("%d" % 123.0, "123")
399*4947cdc7SCole Faustassert.eq("%d" % 1.23e45, "1229999999999999973814869011019624571608236032")
400*4947cdc7SCole Faust# (see below for '%d' % NaN/Inf)
401*4947cdc7SCole Faustassert.eq("%d" % negzero, "0")
402*4947cdc7SCole Faustassert.fails(lambda: "%d" % float("NaN"), "cannot convert float NaN to integer")
403*4947cdc7SCole Faustassert.fails(lambda: "%d" % float("+Inf"), "cannot convert float infinity to integer")
404*4947cdc7SCole Faustassert.fails(lambda: "%d" % float("-Inf"), "cannot convert float infinity to integer")
405*4947cdc7SCole Faust
406*4947cdc7SCole Faust# %e
407*4947cdc7SCole Faustassert.eq("%e" % 0, "0.000000e+00")
408*4947cdc7SCole Faustassert.eq("%e" % 0.0, "0.000000e+00")
409*4947cdc7SCole Faustassert.eq("%e" % 123, "1.230000e+02")
410*4947cdc7SCole Faustassert.eq("%e" % 123.0, "1.230000e+02")
411*4947cdc7SCole Faustassert.eq("%e" % 1.23e45, "1.230000e+45")
412*4947cdc7SCole Faustassert.eq("%e" % -1.23e-45, "-1.230000e-45")
413*4947cdc7SCole Faustassert.eq("%e" % nan, "nan")
414*4947cdc7SCole Faustassert.eq("%e" % inf, "+inf")
415*4947cdc7SCole Faustassert.eq("%e" % neginf, "-inf")
416*4947cdc7SCole Faustassert.eq("%e" % negzero, "-0.000000e+00")
417*4947cdc7SCole Faustassert.fails(lambda: "%e" % "123", "requires float, not str")
418*4947cdc7SCole Faust# %f
419*4947cdc7SCole Faustassert.eq("%f" % 0, "0.000000")
420*4947cdc7SCole Faustassert.eq("%f" % 0.0, "0.000000")
421*4947cdc7SCole Faustassert.eq("%f" % 123, "123.000000")
422*4947cdc7SCole Faustassert.eq("%f" % 123.0, "123.000000")
423*4947cdc7SCole Faust# Note: Starlark/Java emits 1230000000000000000000000000000000000000000000.000000. Why?
424*4947cdc7SCole Faustassert.eq("%f" % 1.23e45, "1229999999999999973814869011019624571608236032.000000")
425*4947cdc7SCole Faustassert.eq("%f" % -1.23e-45, "-0.000000")
426*4947cdc7SCole Faustassert.eq("%f" % nan, "nan")
427*4947cdc7SCole Faustassert.eq("%f" % inf, "+inf")
428*4947cdc7SCole Faustassert.eq("%f" % neginf, "-inf")
429*4947cdc7SCole Faustassert.eq("%f" % negzero, "-0.000000")
430*4947cdc7SCole Faustassert.fails(lambda: "%f" % "123", "requires float, not str")
431*4947cdc7SCole Faust# %g
432*4947cdc7SCole Faustassert.eq("%g" % 0, "0.0")
433*4947cdc7SCole Faustassert.eq("%g" % 0.0, "0.0")
434*4947cdc7SCole Faustassert.eq("%g" % 123, "123.0")
435*4947cdc7SCole Faustassert.eq("%g" % 123.0, "123.0")
436*4947cdc7SCole Faustassert.eq("%g" % 1.110, "1.11")
437*4947cdc7SCole Faustassert.eq("%g" % 1e5, "100000.0")
438*4947cdc7SCole Faustassert.eq("%g" % 1e6, "1e+06") # Note: threshold of scientific notation is 1e17 in Starlark/Java
439*4947cdc7SCole Faustassert.eq("%g" % 1.23e45, "1.23e+45")
440*4947cdc7SCole Faustassert.eq("%g" % -1.23e-45, "-1.23e-45")
441*4947cdc7SCole Faustassert.eq("%g" % nan, "nan")
442*4947cdc7SCole Faustassert.eq("%g" % inf, "+inf")
443*4947cdc7SCole Faustassert.eq("%g" % neginf, "-inf")
444*4947cdc7SCole Faustassert.eq("%g" % negzero, "-0.0")
445*4947cdc7SCole Faust# str uses %g
446*4947cdc7SCole Faustassert.eq(str(0.0), "0.0")
447*4947cdc7SCole Faustassert.eq(str(123.0), "123.0")
448*4947cdc7SCole Faustassert.eq(str(1.23e45), "1.23e+45")
449*4947cdc7SCole Faustassert.eq(str(-1.23e-45), "-1.23e-45")
450*4947cdc7SCole Faustassert.eq(str(nan), "nan")
451*4947cdc7SCole Faustassert.eq(str(inf), "+inf")
452*4947cdc7SCole Faustassert.eq(str(neginf), "-inf")
453*4947cdc7SCole Faustassert.eq(str(negzero), "-0.0")
454*4947cdc7SCole Faustassert.fails(lambda: "%g" % "123", "requires float, not str")
455*4947cdc7SCole Faust
456*4947cdc7SCole Fausti0 = 1
457*4947cdc7SCole Faustf0 = 1.0
458*4947cdc7SCole Faustassert.eq(type(i0), "int")
459*4947cdc7SCole Faustassert.eq(type(f0), "float")
460*4947cdc7SCole Faust
461*4947cdc7SCole Faustops = {
462*4947cdc7SCole Faust    '+': lambda x, y: x + y,
463*4947cdc7SCole Faust    '-': lambda x, y: x - y,
464*4947cdc7SCole Faust    '*': lambda x, y: x * y,
465*4947cdc7SCole Faust    '/': lambda x, y: x / y,
466*4947cdc7SCole Faust    '//': lambda x, y: x // y,
467*4947cdc7SCole Faust    '%': lambda x, y: x % y,
468*4947cdc7SCole Faust}
469*4947cdc7SCole Faust
470*4947cdc7SCole Faust# Check that if either argument is a float, so too is the result.
471*4947cdc7SCole Faustdef checktypes():
472*4947cdc7SCole Faust  want = set("""
473*4947cdc7SCole Faustint + int = int
474*4947cdc7SCole Faustint + float = float
475*4947cdc7SCole Faustfloat + int = float
476*4947cdc7SCole Faustfloat + float = float
477*4947cdc7SCole Faustint - int = int
478*4947cdc7SCole Faustint - float = float
479*4947cdc7SCole Faustfloat - int = float
480*4947cdc7SCole Faustfloat - float = float
481*4947cdc7SCole Faustint * int = int
482*4947cdc7SCole Faustint * float = float
483*4947cdc7SCole Faustfloat * int = float
484*4947cdc7SCole Faustfloat * float = float
485*4947cdc7SCole Faustint / int = float
486*4947cdc7SCole Faustint / float = float
487*4947cdc7SCole Faustfloat / int = float
488*4947cdc7SCole Faustfloat / float = float
489*4947cdc7SCole Faustint // int = int
490*4947cdc7SCole Faustint // float = float
491*4947cdc7SCole Faustfloat // int = float
492*4947cdc7SCole Faustfloat // float = float
493*4947cdc7SCole Faustint % int = int
494*4947cdc7SCole Faustint % float = float
495*4947cdc7SCole Faustfloat % int = float
496*4947cdc7SCole Faustfloat % float = float
497*4947cdc7SCole Faust"""[1:].splitlines())
498*4947cdc7SCole Faust  for opname in ("+", "-", "*", "/", "%"):
499*4947cdc7SCole Faust    for x in [i0, f0]:
500*4947cdc7SCole Faust      for y in [i0, f0]:
501*4947cdc7SCole Faust        op = ops[opname]
502*4947cdc7SCole Faust        got = "%s %s %s = %s" % (type(x), opname, type(y), type(op(x, y)))
503*4947cdc7SCole Faust        assert.contains(want, got)
504*4947cdc7SCole Faustchecktypes()
505