diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-17 14:46:37 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-17 14:46:37 -0200 |
commit | 063d4e4543088e7a21965bda8ee5a0f952a9029e (patch) | |
tree | 6c3f2f8e98c26f071a94a32f9f2754396a66a9de /testes/math.lua | |
parent | e354c6355e7f48e087678ec49e340ca0696725b1 (diff) | |
download | lua-5.3.5.tar.gz lua-5.3.5.tar.bz2 lua-5.3.5.zip |
Lua 5.3.5 ported to gitv5.3.5
This is the first commit for the branch Lua 5.3. All source files
were copied from the official distribution of 5.3.5 in the Lua site.
The test files are the same of 5.3.4. The manual came from the
previous RCS repository, revision 1.167.1.2.
Diffstat (limited to '')
-rw-r--r-- | testes/math.lua | 824 |
1 files changed, 824 insertions, 0 deletions
diff --git a/testes/math.lua b/testes/math.lua new file mode 100644 index 00000000..53ce9b5a --- /dev/null +++ b/testes/math.lua | |||
@@ -0,0 +1,824 @@ | |||
1 | -- $Id: math.lua,v 1.78 2016/11/07 13:11:28 roberto Exp $ | ||
2 | -- See Copyright Notice in file all.lua | ||
3 | |||
4 | print("testing numbers and math lib") | ||
5 | |||
6 | local minint = math.mininteger | ||
7 | local maxint = math.maxinteger | ||
8 | |||
9 | local intbits = math.floor(math.log(maxint, 2) + 0.5) + 1 | ||
10 | assert((1 << intbits) == 0) | ||
11 | |||
12 | assert(minint == 1 << (intbits - 1)) | ||
13 | assert(maxint == minint - 1) | ||
14 | |||
15 | -- number of bits in the mantissa of a floating-point number | ||
16 | local floatbits = 24 | ||
17 | do | ||
18 | local p = 2.0^floatbits | ||
19 | while p < p + 1.0 do | ||
20 | p = p * 2.0 | ||
21 | floatbits = floatbits + 1 | ||
22 | end | ||
23 | end | ||
24 | |||
25 | local function isNaN (x) | ||
26 | return (x ~= x) | ||
27 | end | ||
28 | |||
29 | assert(isNaN(0/0)) | ||
30 | assert(not isNaN(1/0)) | ||
31 | |||
32 | |||
33 | do | ||
34 | local x = 2.0^floatbits | ||
35 | assert(x > x - 1.0 and x == x + 1.0) | ||
36 | |||
37 | print(string.format("%d-bit integers, %d-bit (mantissa) floats", | ||
38 | intbits, floatbits)) | ||
39 | end | ||
40 | |||
41 | assert(math.type(0) == "integer" and math.type(0.0) == "float" | ||
42 | and math.type("10") == nil) | ||
43 | |||
44 | |||
45 | local function checkerror (msg, f, ...) | ||
46 | local s, err = pcall(f, ...) | ||
47 | assert(not s and string.find(err, msg)) | ||
48 | end | ||
49 | |||
50 | local msgf2i = "number.* has no integer representation" | ||
51 | |||
52 | -- float equality | ||
53 | function eq (a,b,limit) | ||
54 | if not limit then | ||
55 | if floatbits >= 50 then limit = 1E-11 | ||
56 | else limit = 1E-5 | ||
57 | end | ||
58 | end | ||
59 | -- a == b needed for +inf/-inf | ||
60 | return a == b or math.abs(a-b) <= limit | ||
61 | end | ||
62 | |||
63 | |||
64 | -- equality with types | ||
65 | function eqT (a,b) | ||
66 | return a == b and math.type(a) == math.type(b) | ||
67 | end | ||
68 | |||
69 | |||
70 | -- basic float notation | ||
71 | assert(0e12 == 0 and .0 == 0 and 0. == 0 and .2e2 == 20 and 2.E-1 == 0.2) | ||
72 | |||
73 | do | ||
74 | local a,b,c = "2", " 3e0 ", " 10 " | ||
75 | assert(a+b == 5 and -b == -3 and b+"2" == 5 and "10"-c == 0) | ||
76 | assert(type(a) == 'string' and type(b) == 'string' and type(c) == 'string') | ||
77 | assert(a == "2" and b == " 3e0 " and c == " 10 " and -c == -" 10 ") | ||
78 | assert(c%a == 0 and a^b == 08) | ||
79 | a = 0 | ||
80 | assert(a == -a and 0 == -0) | ||
81 | end | ||
82 | |||
83 | do | ||
84 | local x = -1 | ||
85 | local mz = 0/x -- minus zero | ||
86 | t = {[0] = 10, 20, 30, 40, 50} | ||
87 | assert(t[mz] == t[0] and t[-0] == t[0]) | ||
88 | end | ||
89 | |||
90 | do -- tests for 'modf' | ||
91 | local a,b = math.modf(3.5) | ||
92 | assert(a == 3.0 and b == 0.5) | ||
93 | a,b = math.modf(-2.5) | ||
94 | assert(a == -2.0 and b == -0.5) | ||
95 | a,b = math.modf(-3e23) | ||
96 | assert(a == -3e23 and b == 0.0) | ||
97 | a,b = math.modf(3e35) | ||
98 | assert(a == 3e35 and b == 0.0) | ||
99 | a,b = math.modf(-1/0) -- -inf | ||
100 | assert(a == -1/0 and b == 0.0) | ||
101 | a,b = math.modf(1/0) -- inf | ||
102 | assert(a == 1/0 and b == 0.0) | ||
103 | a,b = math.modf(0/0) -- NaN | ||
104 | assert(isNaN(a) and isNaN(b)) | ||
105 | a,b = math.modf(3) -- integer argument | ||
106 | assert(eqT(a, 3) and eqT(b, 0.0)) | ||
107 | a,b = math.modf(minint) | ||
108 | assert(eqT(a, minint) and eqT(b, 0.0)) | ||
109 | end | ||
110 | |||
111 | assert(math.huge > 10e30) | ||
112 | assert(-math.huge < -10e30) | ||
113 | |||
114 | |||
115 | -- integer arithmetic | ||
116 | assert(minint < minint + 1) | ||
117 | assert(maxint - 1 < maxint) | ||
118 | assert(0 - minint == minint) | ||
119 | assert(minint * minint == 0) | ||
120 | assert(maxint * maxint * maxint == maxint) | ||
121 | |||
122 | |||
123 | -- testing floor division and conversions | ||
124 | |||
125 | for _, i in pairs{-16, -15, -3, -2, -1, 0, 1, 2, 3, 15} do | ||
126 | for _, j in pairs{-16, -15, -3, -2, -1, 1, 2, 3, 15} do | ||
127 | for _, ti in pairs{0, 0.0} do -- try 'i' as integer and as float | ||
128 | for _, tj in pairs{0, 0.0} do -- try 'j' as integer and as float | ||
129 | local x = i + ti | ||
130 | local y = j + tj | ||
131 | assert(i//j == math.floor(i/j)) | ||
132 | end | ||
133 | end | ||
134 | end | ||
135 | end | ||
136 | |||
137 | assert(1//0.0 == 1/0) | ||
138 | assert(-1 // 0.0 == -1/0) | ||
139 | assert(eqT(3.5 // 1.5, 2.0)) | ||
140 | assert(eqT(3.5 // -1.5, -3.0)) | ||
141 | |||
142 | assert(maxint // maxint == 1) | ||
143 | assert(maxint // 1 == maxint) | ||
144 | assert((maxint - 1) // maxint == 0) | ||
145 | assert(maxint // (maxint - 1) == 1) | ||
146 | assert(minint // minint == 1) | ||
147 | assert(minint // minint == 1) | ||
148 | assert((minint + 1) // minint == 0) | ||
149 | assert(minint // (minint + 1) == 1) | ||
150 | assert(minint // 1 == minint) | ||
151 | |||
152 | assert(minint // -1 == -minint) | ||
153 | assert(minint // -2 == 2^(intbits - 2)) | ||
154 | assert(maxint // -1 == -maxint) | ||
155 | |||
156 | |||
157 | -- negative exponents | ||
158 | do | ||
159 | assert(2^-3 == 1 / 2^3) | ||
160 | assert(eq((-3)^-3, 1 / (-3)^3)) | ||
161 | for i = -3, 3 do -- variables avoid constant folding | ||
162 | for j = -3, 3 do | ||
163 | -- domain errors (0^(-n)) are not portable | ||
164 | if not _port or i ~= 0 or j > 0 then | ||
165 | assert(eq(i^j, 1 / i^(-j))) | ||
166 | end | ||
167 | end | ||
168 | end | ||
169 | end | ||
170 | |||
171 | -- comparison between floats and integers (border cases) | ||
172 | if floatbits < intbits then | ||
173 | assert(2.0^floatbits == (1 << floatbits)) | ||
174 | assert(2.0^floatbits - 1.0 == (1 << floatbits) - 1.0) | ||
175 | assert(2.0^floatbits - 1.0 ~= (1 << floatbits)) | ||
176 | -- float is rounded, int is not | ||
177 | assert(2.0^floatbits + 1.0 ~= (1 << floatbits) + 1) | ||
178 | else -- floats can express all integers with full accuracy | ||
179 | assert(maxint == maxint + 0.0) | ||
180 | assert(maxint - 1 == maxint - 1.0) | ||
181 | assert(minint + 1 == minint + 1.0) | ||
182 | assert(maxint ~= maxint - 1.0) | ||
183 | end | ||
184 | assert(maxint + 0.0 == 2.0^(intbits - 1) - 1.0) | ||
185 | assert(minint + 0.0 == minint) | ||
186 | assert(minint + 0.0 == -2.0^(intbits - 1)) | ||
187 | |||
188 | |||
189 | -- order between floats and integers | ||
190 | assert(1 < 1.1); assert(not (1 < 0.9)) | ||
191 | assert(1 <= 1.1); assert(not (1 <= 0.9)) | ||
192 | assert(-1 < -0.9); assert(not (-1 < -1.1)) | ||
193 | assert(1 <= 1.1); assert(not (-1 <= -1.1)) | ||
194 | assert(-1 < -0.9); assert(not (-1 < -1.1)) | ||
195 | assert(-1 <= -0.9); assert(not (-1 <= -1.1)) | ||
196 | assert(minint <= minint + 0.0) | ||
197 | assert(minint + 0.0 <= minint) | ||
198 | assert(not (minint < minint + 0.0)) | ||
199 | assert(not (minint + 0.0 < minint)) | ||
200 | assert(maxint < minint * -1.0) | ||
201 | assert(maxint <= minint * -1.0) | ||
202 | |||
203 | do | ||
204 | local fmaxi1 = 2^(intbits - 1) | ||
205 | assert(maxint < fmaxi1) | ||
206 | assert(maxint <= fmaxi1) | ||
207 | assert(not (fmaxi1 <= maxint)) | ||
208 | assert(minint <= -2^(intbits - 1)) | ||
209 | assert(-2^(intbits - 1) <= minint) | ||
210 | end | ||
211 | |||
212 | if floatbits < intbits then | ||
213 | print("testing order (floats cannot represent all integers)") | ||
214 | local fmax = 2^floatbits | ||
215 | local ifmax = fmax | 0 | ||
216 | assert(fmax < ifmax + 1) | ||
217 | assert(fmax - 1 < ifmax) | ||
218 | assert(-(fmax - 1) > -ifmax) | ||
219 | assert(not (fmax <= ifmax - 1)) | ||
220 | assert(-fmax > -(ifmax + 1)) | ||
221 | assert(not (-fmax >= -(ifmax - 1))) | ||
222 | |||
223 | assert(fmax/2 - 0.5 < ifmax//2) | ||
224 | assert(-(fmax/2 - 0.5) > -ifmax//2) | ||
225 | |||
226 | assert(maxint < 2^intbits) | ||
227 | assert(minint > -2^intbits) | ||
228 | assert(maxint <= 2^intbits) | ||
229 | assert(minint >= -2^intbits) | ||
230 | else | ||
231 | print("testing order (floats can represent all integers)") | ||
232 | assert(maxint < maxint + 1.0) | ||
233 | assert(maxint < maxint + 0.5) | ||
234 | assert(maxint - 1.0 < maxint) | ||
235 | assert(maxint - 0.5 < maxint) | ||
236 | assert(not (maxint + 0.0 < maxint)) | ||
237 | assert(maxint + 0.0 <= maxint) | ||
238 | assert(not (maxint < maxint + 0.0)) | ||
239 | assert(maxint + 0.0 <= maxint) | ||
240 | assert(maxint <= maxint + 0.0) | ||
241 | assert(not (maxint + 1.0 <= maxint)) | ||
242 | assert(not (maxint + 0.5 <= maxint)) | ||
243 | assert(not (maxint <= maxint - 1.0)) | ||
244 | assert(not (maxint <= maxint - 0.5)) | ||
245 | |||
246 | assert(minint < minint + 1.0) | ||
247 | assert(minint < minint + 0.5) | ||
248 | assert(minint <= minint + 0.5) | ||
249 | assert(minint - 1.0 < minint) | ||
250 | assert(minint - 1.0 <= minint) | ||
251 | assert(not (minint + 0.0 < minint)) | ||
252 | assert(not (minint + 0.5 < minint)) | ||
253 | assert(not (minint < minint + 0.0)) | ||
254 | assert(minint + 0.0 <= minint) | ||
255 | assert(minint <= minint + 0.0) | ||
256 | assert(not (minint + 1.0 <= minint)) | ||
257 | assert(not (minint + 0.5 <= minint)) | ||
258 | assert(not (minint <= minint - 1.0)) | ||
259 | end | ||
260 | |||
261 | do | ||
262 | local NaN = 0/0 | ||
263 | assert(not (NaN < 0)) | ||
264 | assert(not (NaN > minint)) | ||
265 | assert(not (NaN <= -9)) | ||
266 | assert(not (NaN <= maxint)) | ||
267 | assert(not (NaN < maxint)) | ||
268 | assert(not (minint <= NaN)) | ||
269 | assert(not (minint < NaN)) | ||
270 | end | ||
271 | |||
272 | |||
273 | -- avoiding errors at compile time | ||
274 | local function checkcompt (msg, code) | ||
275 | checkerror(msg, assert(load(code))) | ||
276 | end | ||
277 | checkcompt("divide by zero", "return 2 // 0") | ||
278 | checkcompt(msgf2i, "return 2.3 >> 0") | ||
279 | checkcompt(msgf2i, ("return 2.0^%d & 1"):format(intbits - 1)) | ||
280 | checkcompt("field 'huge'", "return math.huge << 1") | ||
281 | checkcompt(msgf2i, ("return 1 | 2.0^%d"):format(intbits - 1)) | ||
282 | checkcompt(msgf2i, "return 2.3 ~ '0.0'") | ||
283 | |||
284 | |||
285 | -- testing overflow errors when converting from float to integer (runtime) | ||
286 | local function f2i (x) return x | x end | ||
287 | checkerror(msgf2i, f2i, math.huge) -- +inf | ||
288 | checkerror(msgf2i, f2i, -math.huge) -- -inf | ||
289 | checkerror(msgf2i, f2i, 0/0) -- NaN | ||
290 | |||
291 | if floatbits < intbits then | ||
292 | -- conversion tests when float cannot represent all integers | ||
293 | assert(maxint + 1.0 == maxint + 0.0) | ||
294 | assert(minint - 1.0 == minint + 0.0) | ||
295 | checkerror(msgf2i, f2i, maxint + 0.0) | ||
296 | assert(f2i(2.0^(intbits - 2)) == 1 << (intbits - 2)) | ||
297 | assert(f2i(-2.0^(intbits - 2)) == -(1 << (intbits - 2))) | ||
298 | assert((2.0^(floatbits - 1) + 1.0) // 1 == (1 << (floatbits - 1)) + 1) | ||
299 | -- maximum integer representable as a float | ||
300 | local mf = maxint - (1 << (floatbits - intbits)) + 1 | ||
301 | assert(f2i(mf + 0.0) == mf) -- OK up to here | ||
302 | mf = mf + 1 | ||
303 | assert(f2i(mf + 0.0) ~= mf) -- no more representable | ||
304 | else | ||
305 | -- conversion tests when float can represent all integers | ||
306 | assert(maxint + 1.0 > maxint) | ||
307 | assert(minint - 1.0 < minint) | ||
308 | assert(f2i(maxint + 0.0) == maxint) | ||
309 | checkerror("no integer rep", f2i, maxint + 1.0) | ||
310 | checkerror("no integer rep", f2i, minint - 1.0) | ||
311 | end | ||
312 | |||
313 | -- 'minint' should be representable as a float no matter the precision | ||
314 | assert(f2i(minint + 0.0) == minint) | ||
315 | |||
316 | |||
317 | -- testing numeric strings | ||
318 | |||
319 | assert("2" + 1 == 3) | ||
320 | assert("2 " + 1 == 3) | ||
321 | assert(" -2 " + 1 == -1) | ||
322 | assert(" -0xa " + 1 == -9) | ||
323 | |||
324 | |||
325 | -- Literal integer Overflows (new behavior in 5.3.3) | ||
326 | do | ||
327 | -- no overflows | ||
328 | assert(eqT(tonumber(tostring(maxint)), maxint)) | ||
329 | assert(eqT(tonumber(tostring(minint)), minint)) | ||
330 | |||
331 | -- add 1 to last digit as a string (it cannot be 9...) | ||
332 | local function incd (n) | ||
333 | local s = string.format("%d", n) | ||
334 | s = string.gsub(s, "%d$", function (d) | ||
335 | assert(d ~= '9') | ||
336 | return string.char(string.byte(d) + 1) | ||
337 | end) | ||
338 | return s | ||
339 | end | ||
340 | |||
341 | -- 'tonumber' with overflow by 1 | ||
342 | assert(eqT(tonumber(incd(maxint)), maxint + 1.0)) | ||
343 | assert(eqT(tonumber(incd(minint)), minint - 1.0)) | ||
344 | |||
345 | -- large numbers | ||
346 | assert(eqT(tonumber("1"..string.rep("0", 30)), 1e30)) | ||
347 | assert(eqT(tonumber("-1"..string.rep("0", 30)), -1e30)) | ||
348 | |||
349 | -- hexa format still wraps around | ||
350 | assert(eqT(tonumber("0x1"..string.rep("0", 30)), 0)) | ||
351 | |||
352 | -- lexer in the limits | ||
353 | assert(minint == load("return " .. minint)()) | ||
354 | assert(eqT(maxint, load("return " .. maxint)())) | ||
355 | |||
356 | assert(eqT(10000000000000000000000.0, 10000000000000000000000)) | ||
357 | assert(eqT(-10000000000000000000000.0, -10000000000000000000000)) | ||
358 | end | ||
359 | |||
360 | |||
361 | -- testing 'tonumber' | ||
362 | |||
363 | -- 'tonumber' with numbers | ||
364 | assert(tonumber(3.4) == 3.4) | ||
365 | assert(eqT(tonumber(3), 3)) | ||
366 | assert(eqT(tonumber(maxint), maxint) and eqT(tonumber(minint), minint)) | ||
367 | assert(tonumber(1/0) == 1/0) | ||
368 | |||
369 | -- 'tonumber' with strings | ||
370 | assert(tonumber("0") == 0) | ||
371 | assert(tonumber("") == nil) | ||
372 | assert(tonumber(" ") == nil) | ||
373 | assert(tonumber("-") == nil) | ||
374 | assert(tonumber(" -0x ") == nil) | ||
375 | assert(tonumber{} == nil) | ||
376 | assert(tonumber'+0.01' == 1/100 and tonumber'+.01' == 0.01 and | ||
377 | tonumber'.01' == 0.01 and tonumber'-1.' == -1 and | ||
378 | tonumber'+1.' == 1) | ||
379 | assert(tonumber'+ 0.01' == nil and tonumber'+.e1' == nil and | ||
380 | tonumber'1e' == nil and tonumber'1.0e+' == nil and | ||
381 | tonumber'.' == nil) | ||
382 | assert(tonumber('-012') == -010-2) | ||
383 | assert(tonumber('-1.2e2') == - - -120) | ||
384 | |||
385 | assert(tonumber("0xffffffffffff") == (1 << (4*12)) - 1) | ||
386 | assert(tonumber("0x"..string.rep("f", (intbits//4))) == -1) | ||
387 | assert(tonumber("-0x"..string.rep("f", (intbits//4))) == 1) | ||
388 | |||
389 | -- testing 'tonumber' with base | ||
390 | assert(tonumber(' 001010 ', 2) == 10) | ||
391 | assert(tonumber(' 001010 ', 10) == 001010) | ||
392 | assert(tonumber(' -1010 ', 2) == -10) | ||
393 | assert(tonumber('10', 36) == 36) | ||
394 | assert(tonumber(' -10 ', 36) == -36) | ||
395 | assert(tonumber(' +1Z ', 36) == 36 + 35) | ||
396 | assert(tonumber(' -1z ', 36) == -36 + -35) | ||
397 | assert(tonumber('-fFfa', 16) == -(10+(16*(15+(16*(15+(16*15))))))) | ||
398 | assert(tonumber(string.rep('1', (intbits - 2)), 2) + 1 == 2^(intbits - 2)) | ||
399 | assert(tonumber('ffffFFFF', 16)+1 == (1 << 32)) | ||
400 | assert(tonumber('0ffffFFFF', 16)+1 == (1 << 32)) | ||
401 | assert(tonumber('-0ffffffFFFF', 16) - 1 == -(1 << 40)) | ||
402 | for i = 2,36 do | ||
403 | local i2 = i * i | ||
404 | local i10 = i2 * i2 * i2 * i2 * i2 -- i^10 | ||
405 | assert(tonumber('\t10000000000\t', i) == i10) | ||
406 | end | ||
407 | |||
408 | if not _soft then | ||
409 | -- tests with very long numerals | ||
410 | assert(tonumber("0x"..string.rep("f", 13)..".0") == 2.0^(4*13) - 1) | ||
411 | assert(tonumber("0x"..string.rep("f", 150)..".0") == 2.0^(4*150) - 1) | ||
412 | assert(tonumber("0x"..string.rep("f", 300)..".0") == 2.0^(4*300) - 1) | ||
413 | assert(tonumber("0x"..string.rep("f", 500)..".0") == 2.0^(4*500) - 1) | ||
414 | assert(tonumber('0x3.' .. string.rep('0', 1000)) == 3) | ||
415 | assert(tonumber('0x' .. string.rep('0', 1000) .. 'a') == 10) | ||
416 | assert(tonumber('0x0.' .. string.rep('0', 13).."1") == 2.0^(-4*14)) | ||
417 | assert(tonumber('0x0.' .. string.rep('0', 150).."1") == 2.0^(-4*151)) | ||
418 | assert(tonumber('0x0.' .. string.rep('0', 300).."1") == 2.0^(-4*301)) | ||
419 | assert(tonumber('0x0.' .. string.rep('0', 500).."1") == 2.0^(-4*501)) | ||
420 | |||
421 | assert(tonumber('0xe03' .. string.rep('0', 1000) .. 'p-4000') == 3587.0) | ||
422 | assert(tonumber('0x.' .. string.rep('0', 1000) .. '74p4004') == 0x7.4) | ||
423 | end | ||
424 | |||
425 | -- testing 'tonumber' for invalid formats | ||
426 | |||
427 | local function f (...) | ||
428 | if select('#', ...) == 1 then | ||
429 | return (...) | ||
430 | else | ||
431 | return "***" | ||
432 | end | ||
433 | end | ||
434 | |||
435 | assert(f(tonumber('fFfa', 15)) == nil) | ||
436 | assert(f(tonumber('099', 8)) == nil) | ||
437 | assert(f(tonumber('1\0', 2)) == nil) | ||
438 | assert(f(tonumber('', 8)) == nil) | ||
439 | assert(f(tonumber(' ', 9)) == nil) | ||
440 | assert(f(tonumber(' ', 9)) == nil) | ||
441 | assert(f(tonumber('0xf', 10)) == nil) | ||
442 | |||
443 | assert(f(tonumber('inf')) == nil) | ||
444 | assert(f(tonumber(' INF ')) == nil) | ||
445 | assert(f(tonumber('Nan')) == nil) | ||
446 | assert(f(tonumber('nan')) == nil) | ||
447 | |||
448 | assert(f(tonumber(' ')) == nil) | ||
449 | assert(f(tonumber('')) == nil) | ||
450 | assert(f(tonumber('1 a')) == nil) | ||
451 | assert(f(tonumber('1 a', 2)) == nil) | ||
452 | assert(f(tonumber('1\0')) == nil) | ||
453 | assert(f(tonumber('1 \0')) == nil) | ||
454 | assert(f(tonumber('1\0 ')) == nil) | ||
455 | assert(f(tonumber('e1')) == nil) | ||
456 | assert(f(tonumber('e 1')) == nil) | ||
457 | assert(f(tonumber(' 3.4.5 ')) == nil) | ||
458 | |||
459 | |||
460 | -- testing 'tonumber' for invalid hexadecimal formats | ||
461 | |||
462 | assert(tonumber('0x') == nil) | ||
463 | assert(tonumber('x') == nil) | ||
464 | assert(tonumber('x3') == nil) | ||
465 | assert(tonumber('0x3.3.3') == nil) -- two decimal points | ||
466 | assert(tonumber('00x2') == nil) | ||
467 | assert(tonumber('0x 2') == nil) | ||
468 | assert(tonumber('0 x2') == nil) | ||
469 | assert(tonumber('23x') == nil) | ||
470 | assert(tonumber('- 0xaa') == nil) | ||
471 | assert(tonumber('-0xaaP ') == nil) -- no exponent | ||
472 | assert(tonumber('0x0.51p') == nil) | ||
473 | assert(tonumber('0x5p+-2') == nil) | ||
474 | |||
475 | |||
476 | -- testing hexadecimal numerals | ||
477 | |||
478 | assert(0x10 == 16 and 0xfff == 2^12 - 1 and 0XFB == 251) | ||
479 | assert(0x0p12 == 0 and 0x.0p-3 == 0) | ||
480 | assert(0xFFFFFFFF == (1 << 32) - 1) | ||
481 | assert(tonumber('+0x2') == 2) | ||
482 | assert(tonumber('-0xaA') == -170) | ||
483 | assert(tonumber('-0xffFFFfff') == -(1 << 32) + 1) | ||
484 | |||
485 | -- possible confusion with decimal exponent | ||
486 | assert(0E+1 == 0 and 0xE+1 == 15 and 0xe-1 == 13) | ||
487 | |||
488 | |||
489 | -- floating hexas | ||
490 | |||
491 | assert(tonumber(' 0x2.5 ') == 0x25/16) | ||
492 | assert(tonumber(' -0x2.5 ') == -0x25/16) | ||
493 | assert(tonumber(' +0x0.51p+8 ') == 0x51) | ||
494 | assert(0x.FfffFFFF == 1 - '0x.00000001') | ||
495 | assert('0xA.a' + 0 == 10 + 10/16) | ||
496 | assert(0xa.aP4 == 0XAA) | ||
497 | assert(0x4P-2 == 1) | ||
498 | assert(0x1.1 == '0x1.' + '+0x.1') | ||
499 | assert(0Xabcdef.0 == 0x.ABCDEFp+24) | ||
500 | |||
501 | |||
502 | assert(1.1 == 1.+.1) | ||
503 | assert(100.0 == 1E2 and .01 == 1e-2) | ||
504 | assert(1111111111 - 1111111110 == 1000.00e-03) | ||
505 | assert(1.1 == '1.'+'.1') | ||
506 | assert(tonumber'1111111111' - tonumber'1111111110' == | ||
507 | tonumber" +0.001e+3 \n\t") | ||
508 | |||
509 | assert(0.1e-30 > 0.9E-31 and 0.9E30 < 0.1e31) | ||
510 | |||
511 | assert(0.123456 > 0.123455) | ||
512 | |||
513 | assert(tonumber('+1.23E18') == 1.23*10.0^18) | ||
514 | |||
515 | -- testing order operators | ||
516 | assert(not(1<1) and (1<2) and not(2<1)) | ||
517 | assert(not('a'<'a') and ('a'<'b') and not('b'<'a')) | ||
518 | assert((1<=1) and (1<=2) and not(2<=1)) | ||
519 | assert(('a'<='a') and ('a'<='b') and not('b'<='a')) | ||
520 | assert(not(1>1) and not(1>2) and (2>1)) | ||
521 | assert(not('a'>'a') and not('a'>'b') and ('b'>'a')) | ||
522 | assert((1>=1) and not(1>=2) and (2>=1)) | ||
523 | assert(('a'>='a') and not('a'>='b') and ('b'>='a')) | ||
524 | assert(1.3 < 1.4 and 1.3 <= 1.4 and not (1.3 < 1.3) and 1.3 <= 1.3) | ||
525 | |||
526 | -- testing mod operator | ||
527 | assert(eqT(-4 % 3, 2)) | ||
528 | assert(eqT(4 % -3, -2)) | ||
529 | assert(eqT(-4.0 % 3, 2.0)) | ||
530 | assert(eqT(4 % -3.0, -2.0)) | ||
531 | assert(math.pi - math.pi % 1 == 3) | ||
532 | assert(math.pi - math.pi % 0.001 == 3.141) | ||
533 | |||
534 | assert(eqT(minint % minint, 0)) | ||
535 | assert(eqT(maxint % maxint, 0)) | ||
536 | assert((minint + 1) % minint == minint + 1) | ||
537 | assert((maxint - 1) % maxint == maxint - 1) | ||
538 | assert(minint % maxint == maxint - 1) | ||
539 | |||
540 | assert(minint % -1 == 0) | ||
541 | assert(minint % -2 == 0) | ||
542 | assert(maxint % -2 == -1) | ||
543 | |||
544 | -- non-portable tests because Windows C library cannot compute | ||
545 | -- fmod(1, huge) correctly | ||
546 | if not _port then | ||
547 | local function anan (x) assert(isNaN(x)) end -- assert Not a Number | ||
548 | anan(0.0 % 0) | ||
549 | anan(1.3 % 0) | ||
550 | anan(math.huge % 1) | ||
551 | anan(math.huge % 1e30) | ||
552 | anan(-math.huge % 1e30) | ||
553 | anan(-math.huge % -1e30) | ||
554 | assert(1 % math.huge == 1) | ||
555 | assert(1e30 % math.huge == 1e30) | ||
556 | assert(1e30 % -math.huge == -math.huge) | ||
557 | assert(-1 % math.huge == math.huge) | ||
558 | assert(-1 % -math.huge == -1) | ||
559 | end | ||
560 | |||
561 | |||
562 | -- testing unsigned comparisons | ||
563 | assert(math.ult(3, 4)) | ||
564 | assert(not math.ult(4, 4)) | ||
565 | assert(math.ult(-2, -1)) | ||
566 | assert(math.ult(2, -1)) | ||
567 | assert(not math.ult(-2, -2)) | ||
568 | assert(math.ult(maxint, minint)) | ||
569 | assert(not math.ult(minint, maxint)) | ||
570 | |||
571 | |||
572 | assert(eq(math.sin(-9.8)^2 + math.cos(-9.8)^2, 1)) | ||
573 | assert(eq(math.tan(math.pi/4), 1)) | ||
574 | assert(eq(math.sin(math.pi/2), 1) and eq(math.cos(math.pi/2), 0)) | ||
575 | assert(eq(math.atan(1), math.pi/4) and eq(math.acos(0), math.pi/2) and | ||
576 | eq(math.asin(1), math.pi/2)) | ||
577 | assert(eq(math.deg(math.pi/2), 90) and eq(math.rad(90), math.pi/2)) | ||
578 | assert(math.abs(-10.43) == 10.43) | ||
579 | assert(eqT(math.abs(minint), minint)) | ||
580 | assert(eqT(math.abs(maxint), maxint)) | ||
581 | assert(eqT(math.abs(-maxint), maxint)) | ||
582 | assert(eq(math.atan(1,0), math.pi/2)) | ||
583 | assert(math.fmod(10,3) == 1) | ||
584 | assert(eq(math.sqrt(10)^2, 10)) | ||
585 | assert(eq(math.log(2, 10), math.log(2)/math.log(10))) | ||
586 | assert(eq(math.log(2, 2), 1)) | ||
587 | assert(eq(math.log(9, 3), 2)) | ||
588 | assert(eq(math.exp(0), 1)) | ||
589 | assert(eq(math.sin(10), math.sin(10%(2*math.pi)))) | ||
590 | |||
591 | |||
592 | assert(tonumber(' 1.3e-2 ') == 1.3e-2) | ||
593 | assert(tonumber(' -1.00000000000001 ') == -1.00000000000001) | ||
594 | |||
595 | -- testing constant limits | ||
596 | -- 2^23 = 8388608 | ||
597 | assert(8388609 + -8388609 == 0) | ||
598 | assert(8388608 + -8388608 == 0) | ||
599 | assert(8388607 + -8388607 == 0) | ||
600 | |||
601 | |||
602 | |||
603 | do -- testing floor & ceil | ||
604 | assert(eqT(math.floor(3.4), 3)) | ||
605 | assert(eqT(math.ceil(3.4), 4)) | ||
606 | assert(eqT(math.floor(-3.4), -4)) | ||
607 | assert(eqT(math.ceil(-3.4), -3)) | ||
608 | assert(eqT(math.floor(maxint), maxint)) | ||
609 | assert(eqT(math.ceil(maxint), maxint)) | ||
610 | assert(eqT(math.floor(minint), minint)) | ||
611 | assert(eqT(math.floor(minint + 0.0), minint)) | ||
612 | assert(eqT(math.ceil(minint), minint)) | ||
613 | assert(eqT(math.ceil(minint + 0.0), minint)) | ||
614 | assert(math.floor(1e50) == 1e50) | ||
615 | assert(math.ceil(1e50) == 1e50) | ||
616 | assert(math.floor(-1e50) == -1e50) | ||
617 | assert(math.ceil(-1e50) == -1e50) | ||
618 | for _, p in pairs{31,32,63,64} do | ||
619 | assert(math.floor(2^p) == 2^p) | ||
620 | assert(math.floor(2^p + 0.5) == 2^p) | ||
621 | assert(math.ceil(2^p) == 2^p) | ||
622 | assert(math.ceil(2^p - 0.5) == 2^p) | ||
623 | end | ||
624 | checkerror("number expected", math.floor, {}) | ||
625 | checkerror("number expected", math.ceil, print) | ||
626 | assert(eqT(math.tointeger(minint), minint)) | ||
627 | assert(eqT(math.tointeger(minint .. ""), minint)) | ||
628 | assert(eqT(math.tointeger(maxint), maxint)) | ||
629 | assert(eqT(math.tointeger(maxint .. ""), maxint)) | ||
630 | assert(eqT(math.tointeger(minint + 0.0), minint)) | ||
631 | assert(math.tointeger(0.0 - minint) == nil) | ||
632 | assert(math.tointeger(math.pi) == nil) | ||
633 | assert(math.tointeger(-math.pi) == nil) | ||
634 | assert(math.floor(math.huge) == math.huge) | ||
635 | assert(math.ceil(math.huge) == math.huge) | ||
636 | assert(math.tointeger(math.huge) == nil) | ||
637 | assert(math.floor(-math.huge) == -math.huge) | ||
638 | assert(math.ceil(-math.huge) == -math.huge) | ||
639 | assert(math.tointeger(-math.huge) == nil) | ||
640 | assert(math.tointeger("34.0") == 34) | ||
641 | assert(math.tointeger("34.3") == nil) | ||
642 | assert(math.tointeger({}) == nil) | ||
643 | assert(math.tointeger(0/0) == nil) -- NaN | ||
644 | end | ||
645 | |||
646 | |||
647 | -- testing fmod for integers | ||
648 | for i = -6, 6 do | ||
649 | for j = -6, 6 do | ||
650 | if j ~= 0 then | ||
651 | local mi = math.fmod(i, j) | ||
652 | local mf = math.fmod(i + 0.0, j) | ||
653 | assert(mi == mf) | ||
654 | assert(math.type(mi) == 'integer' and math.type(mf) == 'float') | ||
655 | if (i >= 0 and j >= 0) or (i <= 0 and j <= 0) or mi == 0 then | ||
656 | assert(eqT(mi, i % j)) | ||
657 | end | ||
658 | end | ||
659 | end | ||
660 | end | ||
661 | assert(eqT(math.fmod(minint, minint), 0)) | ||
662 | assert(eqT(math.fmod(maxint, maxint), 0)) | ||
663 | assert(eqT(math.fmod(minint + 1, minint), minint + 1)) | ||
664 | assert(eqT(math.fmod(maxint - 1, maxint), maxint - 1)) | ||
665 | |||
666 | checkerror("zero", math.fmod, 3, 0) | ||
667 | |||
668 | |||
669 | do -- testing max/min | ||
670 | checkerror("value expected", math.max) | ||
671 | checkerror("value expected", math.min) | ||
672 | assert(eqT(math.max(3), 3)) | ||
673 | assert(eqT(math.max(3, 5, 9, 1), 9)) | ||
674 | assert(math.max(maxint, 10e60) == 10e60) | ||
675 | assert(eqT(math.max(minint, minint + 1), minint + 1)) | ||
676 | assert(eqT(math.min(3), 3)) | ||
677 | assert(eqT(math.min(3, 5, 9, 1), 1)) | ||
678 | assert(math.min(3.2, 5.9, -9.2, 1.1) == -9.2) | ||
679 | assert(math.min(1.9, 1.7, 1.72) == 1.7) | ||
680 | assert(math.min(-10e60, minint) == -10e60) | ||
681 | assert(eqT(math.min(maxint, maxint - 1), maxint - 1)) | ||
682 | assert(eqT(math.min(maxint - 2, maxint, maxint - 1), maxint - 2)) | ||
683 | end | ||
684 | -- testing implicit convertions | ||
685 | |||
686 | local a,b = '10', '20' | ||
687 | assert(a*b == 200 and a+b == 30 and a-b == -10 and a/b == 0.5 and -b == -20) | ||
688 | assert(a == '10' and b == '20') | ||
689 | |||
690 | |||
691 | do | ||
692 | print("testing -0 and NaN") | ||
693 | local mz, z = -0.0, 0.0 | ||
694 | assert(mz == z) | ||
695 | assert(1/mz < 0 and 0 < 1/z) | ||
696 | local a = {[mz] = 1} | ||
697 | assert(a[z] == 1 and a[mz] == 1) | ||
698 | a[z] = 2 | ||
699 | assert(a[z] == 2 and a[mz] == 2) | ||
700 | local inf = math.huge * 2 + 1 | ||
701 | mz, z = -1/inf, 1/inf | ||
702 | assert(mz == z) | ||
703 | assert(1/mz < 0 and 0 < 1/z) | ||
704 | local NaN = inf - inf | ||
705 | assert(NaN ~= NaN) | ||
706 | assert(not (NaN < NaN)) | ||
707 | assert(not (NaN <= NaN)) | ||
708 | assert(not (NaN > NaN)) | ||
709 | assert(not (NaN >= NaN)) | ||
710 | assert(not (0 < NaN) and not (NaN < 0)) | ||
711 | local NaN1 = 0/0 | ||
712 | assert(NaN ~= NaN1 and not (NaN <= NaN1) and not (NaN1 <= NaN)) | ||
713 | local a = {} | ||
714 | assert(not pcall(rawset, a, NaN, 1)) | ||
715 | assert(a[NaN] == nil) | ||
716 | a[1] = 1 | ||
717 | assert(not pcall(rawset, a, NaN, 1)) | ||
718 | assert(a[NaN] == nil) | ||
719 | -- strings with same binary representation as 0.0 (might create problems | ||
720 | -- for constant manipulation in the pre-compiler) | ||
721 | local a1, a2, a3, a4, a5 = 0, 0, "\0\0\0\0\0\0\0\0", 0, "\0\0\0\0\0\0\0\0" | ||
722 | assert(a1 == a2 and a2 == a4 and a1 ~= a3) | ||
723 | assert(a3 == a5) | ||
724 | end | ||
725 | |||
726 | |||
727 | print("testing 'math.random'") | ||
728 | math.randomseed(0) | ||
729 | |||
730 | do -- test random for floats | ||
731 | local max = -math.huge | ||
732 | local min = math.huge | ||
733 | for i = 0, 20000 do | ||
734 | local t = math.random() | ||
735 | assert(0 <= t and t < 1) | ||
736 | max = math.max(max, t) | ||
737 | min = math.min(min, t) | ||
738 | if eq(max, 1, 0.001) and eq(min, 0, 0.001) then | ||
739 | goto ok | ||
740 | end | ||
741 | end | ||
742 | -- loop ended without satisfing condition | ||
743 | assert(false) | ||
744 | ::ok:: | ||
745 | end | ||
746 | |||
747 | do | ||
748 | local function aux (p, lim) -- test random for small intervals | ||
749 | local x1, x2 | ||
750 | if #p == 1 then x1 = 1; x2 = p[1] | ||
751 | else x1 = p[1]; x2 = p[2] | ||
752 | end | ||
753 | local mark = {}; local count = 0 -- to check that all values appeared | ||
754 | for i = 0, lim or 2000 do | ||
755 | local t = math.random(table.unpack(p)) | ||
756 | assert(x1 <= t and t <= x2) | ||
757 | if not mark[t] then -- new value | ||
758 | mark[t] = true | ||
759 | count = count + 1 | ||
760 | end | ||
761 | if count == x2 - x1 + 1 then -- all values appeared; OK | ||
762 | goto ok | ||
763 | end | ||
764 | end | ||
765 | -- loop ended without satisfing condition | ||
766 | assert(false) | ||
767 | ::ok:: | ||
768 | end | ||
769 | |||
770 | aux({-10,0}) | ||
771 | aux({6}) | ||
772 | aux({-10, 10}) | ||
773 | aux({minint, minint}) | ||
774 | aux({maxint, maxint}) | ||
775 | aux({minint, minint + 9}) | ||
776 | aux({maxint - 3, maxint}) | ||
777 | end | ||
778 | |||
779 | do | ||
780 | local function aux(p1, p2) -- test random for large intervals | ||
781 | local max = minint | ||
782 | local min = maxint | ||
783 | local n = 200 | ||
784 | local mark = {}; local count = 0 -- to count how many different values | ||
785 | for _ = 1, n do | ||
786 | local t = math.random(p1, p2) | ||
787 | max = math.max(max, t) | ||
788 | min = math.min(min, t) | ||
789 | if not mark[t] then -- new value | ||
790 | mark[t] = true | ||
791 | count = count + 1 | ||
792 | end | ||
793 | end | ||
794 | -- at least 80% of values are different | ||
795 | assert(count >= n * 0.8) | ||
796 | -- min and max not too far from formal min and max | ||
797 | local diff = (p2 - p1) // 8 | ||
798 | assert(min < p1 + diff and max > p2 - diff) | ||
799 | end | ||
800 | aux(0, maxint) | ||
801 | aux(1, maxint) | ||
802 | aux(minint, -1) | ||
803 | aux(minint // 2, maxint // 2) | ||
804 | end | ||
805 | |||
806 | for i=1,100 do | ||
807 | assert(math.random(maxint) > 0) | ||
808 | assert(math.random(minint, -1) < 0) | ||
809 | end | ||
810 | |||
811 | assert(not pcall(math.random, 1, 2, 3)) -- too many arguments | ||
812 | |||
813 | -- empty interval | ||
814 | assert(not pcall(math.random, minint + 1, minint)) | ||
815 | assert(not pcall(math.random, maxint, maxint - 1)) | ||
816 | assert(not pcall(math.random, maxint, minint)) | ||
817 | |||
818 | -- interval too large | ||
819 | assert(not pcall(math.random, minint, 0)) | ||
820 | assert(not pcall(math.random, -1, maxint)) | ||
821 | assert(not pcall(math.random, minint // 2, maxint // 2 + 1)) | ||
822 | |||
823 | |||
824 | print('OK') | ||