1-- $Id: testes/math.lua $
2-- See Copyright Notice in file all.lua
3
4print("testing numbers and math lib")
5
6local minint <const> = math.mininteger
7local maxint <const> = math.maxinteger
8
9local intbits <const> = math.floor(math.log(maxint, 2) + 0.5) + 1
10assert((1 << intbits) == 0)
11
12assert(minint == 1 << (intbits - 1))
13assert(maxint == minint - 1)
14
15-- number of bits in the mantissa of a floating-point number
16local floatbits = 24
17do
18 local p = 2.0^floatbits
19 while p < p + 1.0 do
20 p = p * 2.0
21 floatbits = floatbits + 1
22 end
23end
24
25local function isNaN (x)
26 return (x ~= x)
27end
28
29assert(isNaN(0/0))
30assert(not isNaN(1/0))
31
32
33do
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))
39end
40
41assert(math.type(0) == "integer" and math.type(0.0) == "float"
42 and not math.type("10"))
43
44
45local function checkerror (msg, f, ...)
46 local s, err = pcall(f, ...)
47 assert(not s and string.find(err, msg))
48end
49
50local msgf2i = "number.* has no integer representation"
51
52-- float equality
53local 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
61end
62
63
64-- equality with types
65local function eqT (a,b)
66 return a == b and math.type(a) == math.type(b)
67end
68
69
70-- basic float notation
71assert(0e12 == 0 and .0 == 0 and 0. == 0 and .2e2 == 20 and 2.E-1 == 0.2)
72
73do
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)
81end
82
83do
84 local x = -1
85 local mz = 0/x -- minus zero
86 local t = {[0] = 10, 20, 30, 40, 50}
87 assert(t[mz] == t[0] and t[-0] == t[0])
88end
89
90do -- 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))
109end
110
111assert(math.huge > 10e30)
112assert(-math.huge < -10e30)
113
114
115-- integer arithmetic
116assert(minint < minint + 1)
117assert(maxint - 1 < maxint)
118assert(0 - minint == minint)
119assert(minint * minint == 0)
120assert(maxint * maxint * maxint == maxint)
121
122
123-- testing floor division and conversions
124
125for _, 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
135end
136
137assert(1//0.0 == 1/0)
138assert(-1 // 0.0 == -1/0)
139assert(eqT(3.5 // 1.5, 2.0))
140assert(eqT(3.5 // -1.5, -3.0))
141
142do -- tests for different kinds of opcodes
143 local x, y
144 x = 1; assert(x // 0.0 == 1/0)
145 x = 1.0; assert(x // 0 == 1/0)
146 x = 3.5; assert(eqT(x // 1, 3.0))
147 assert(eqT(x // -1, -4.0))
148
149 x = 3.5; y = 1.5; assert(eqT(x // y, 2.0))
150 x = 3.5; y = -1.5; assert(eqT(x // y, -3.0))
151end
152
153assert(maxint // maxint == 1)
154assert(maxint // 1 == maxint)
155assert((maxint - 1) // maxint == 0)
156assert(maxint // (maxint - 1) == 1)
157assert(minint // minint == 1)
158assert(minint // minint == 1)
159assert((minint + 1) // minint == 0)
160assert(minint // (minint + 1) == 1)
161assert(minint // 1 == minint)
162
163assert(minint // -1 == -minint)
164assert(minint // -2 == 2^(intbits - 2))
165assert(maxint // -1 == -maxint)
166
167
168-- negative exponents
169do
170 assert(2^-3 == 1 / 2^3)
171 assert(eq((-3)^-3, 1 / (-3)^3))
172 for i = -3, 3 do -- variables avoid constant folding
173 for j = -3, 3 do
174 -- domain errors (0^(-n)) are not portable
175 if not _port or i ~= 0 or j > 0 then
176 assert(eq(i^j, 1 / i^(-j)))
177 end
178 end
179 end
180end
181
182-- comparison between floats and integers (border cases)
183if floatbits < intbits then
184 assert(2.0^floatbits == (1 << floatbits))
185 assert(2.0^floatbits - 1.0 == (1 << floatbits) - 1.0)
186 assert(2.0^floatbits - 1.0 ~= (1 << floatbits))
187 -- float is rounded, int is not
188 assert(2.0^floatbits + 1.0 ~= (1 << floatbits) + 1)
189else -- floats can express all integers with full accuracy
190 assert(maxint == maxint + 0.0)
191 assert(maxint - 1 == maxint - 1.0)
192 assert(minint + 1 == minint + 1.0)
193 assert(maxint ~= maxint - 1.0)
194end
195assert(maxint + 0.0 == 2.0^(intbits - 1) - 1.0)
196assert(minint + 0.0 == minint)
197assert(minint + 0.0 == -2.0^(intbits - 1))
198
199
200-- order between floats and integers
201assert(1 < 1.1); assert(not (1 < 0.9))
202assert(1 <= 1.1); assert(not (1 <= 0.9))
203assert(-1 < -0.9); assert(not (-1 < -1.1))
204assert(1 <= 1.1); assert(not (-1 <= -1.1))
205assert(-1 < -0.9); assert(not (-1 < -1.1))
206assert(-1 <= -0.9); assert(not (-1 <= -1.1))
207assert(minint <= minint + 0.0)
208assert(minint + 0.0 <= minint)
209assert(not (minint < minint + 0.0))
210assert(not (minint + 0.0 < minint))
211assert(maxint < minint * -1.0)
212assert(maxint <= minint * -1.0)
213
214do
215 local fmaxi1 = 2^(intbits - 1)
216 assert(maxint < fmaxi1)
217 assert(maxint <= fmaxi1)
218 assert(not (fmaxi1 <= maxint))
219 assert(minint <= -2^(intbits - 1))
220 assert(-2^(intbits - 1) <= minint)
221end
222
223if floatbits < intbits then
224 print("testing order (floats cannot represent all integers)")
225 local fmax = 2^floatbits
226 local ifmax = fmax | 0
227 assert(fmax < ifmax + 1)
228 assert(fmax - 1 < ifmax)
229 assert(-(fmax - 1) > -ifmax)
230 assert(not (fmax <= ifmax - 1))
231 assert(-fmax > -(ifmax + 1))
232 assert(not (-fmax >= -(ifmax - 1)))
233
234 assert(fmax/2 - 0.5 < ifmax//2)
235 assert(-(fmax/2 - 0.5) > -ifmax//2)
236
237 assert(maxint < 2^intbits)
238 assert(minint > -2^intbits)
239 assert(maxint <= 2^intbits)
240 assert(minint >= -2^intbits)
241else
242 print("testing order (floats can represent all integers)")
243 assert(maxint < maxint + 1.0)
244 assert(maxint < maxint + 0.5)
245 assert(maxint - 1.0 < maxint)
246 assert(maxint - 0.5 < maxint)
247 assert(not (maxint + 0.0 < maxint))
248 assert(maxint + 0.0 <= maxint)
249 assert(not (maxint < maxint + 0.0))
250 assert(maxint + 0.0 <= maxint)
251 assert(maxint <= maxint + 0.0)
252 assert(not (maxint + 1.0 <= maxint))
253 assert(not (maxint + 0.5 <= maxint))
254 assert(not (maxint <= maxint - 1.0))
255 assert(not (maxint <= maxint - 0.5))
256
257 assert(minint < minint + 1.0)
258 assert(minint < minint + 0.5)
259 assert(minint <= minint + 0.5)
260 assert(minint - 1.0 < minint)
261 assert(minint - 1.0 <= minint)
262 assert(not (minint + 0.0 < minint))
263 assert(not (minint + 0.5 < minint))
264 assert(not (minint < minint + 0.0))
265 assert(minint + 0.0 <= minint)
266 assert(minint <= minint + 0.0)
267 assert(not (minint + 1.0 <= minint))
268 assert(not (minint + 0.5 <= minint))
269 assert(not (minint <= minint - 1.0))
270end
271
272do
273 local NaN <const> = 0/0
274 assert(not (NaN < 0))
275 assert(not (NaN > minint))
276 assert(not (NaN <= -9))
277 assert(not (NaN <= maxint))
278 assert(not (NaN < maxint))
279 assert(not (minint <= NaN))
280 assert(not (minint < NaN))
281 assert(not (4 <= NaN))
282 assert(not (4 < NaN))
283end
284
285
286-- avoiding errors at compile time
287local function checkcompt (msg, code)
288 checkerror(msg, assert(load(code)))
289end
290checkcompt("divide by zero", "return 2 // 0")
291checkcompt(msgf2i, "return 2.3 >> 0")
292checkcompt(msgf2i, ("return 2.0^%d & 1"):format(intbits - 1))
293checkcompt("field 'huge'", "return math.huge << 1")
294checkcompt(msgf2i, ("return 1 | 2.0^%d"):format(intbits - 1))
295checkcompt(msgf2i, "return 2.3 ~ 0.0")
296
297
298-- testing overflow errors when converting from float to integer (runtime)
299local function f2i (x) return x | x end
300checkerror(msgf2i, f2i, math.huge) -- +inf
301checkerror(msgf2i, f2i, -math.huge) -- -inf
302checkerror(msgf2i, f2i, 0/0) -- NaN
303
304if floatbits < intbits then
305 -- conversion tests when float cannot represent all integers
306 assert(maxint + 1.0 == maxint + 0.0)
307 assert(minint - 1.0 == minint + 0.0)
308 checkerror(msgf2i, f2i, maxint + 0.0)
309 assert(f2i(2.0^(intbits - 2)) == 1 << (intbits - 2))
310 assert(f2i(-2.0^(intbits - 2)) == -(1 << (intbits - 2)))
311 assert((2.0^(floatbits - 1) + 1.0) // 1 == (1 << (floatbits - 1)) + 1)
312 -- maximum integer representable as a float
313 local mf = maxint - (1 << (floatbits - intbits)) + 1
314 assert(f2i(mf + 0.0) == mf) -- OK up to here
315 mf = mf + 1
316 assert(f2i(mf + 0.0) ~= mf) -- no more representable
317else
318 -- conversion tests when float can represent all integers
319 assert(maxint + 1.0 > maxint)
320 assert(minint - 1.0 < minint)
321 assert(f2i(maxint + 0.0) == maxint)
322 checkerror("no integer rep", f2i, maxint + 1.0)
323 checkerror("no integer rep", f2i, minint - 1.0)
324end
325
326-- 'minint' should be representable as a float no matter the precision
327assert(f2i(minint + 0.0) == minint)
328
329
330-- testing numeric strings
331
332assert("2" + 1 == 3)
333assert("2 " + 1 == 3)
334assert(" -2 " + 1 == -1)
335assert(" -0xa " + 1 == -9)
336
337
338-- Literal integer Overflows (new behavior in 5.3.3)
339do
340 -- no overflows
341 assert(eqT(tonumber(tostring(maxint)), maxint))
342 assert(eqT(tonumber(tostring(minint)), minint))
343
344 -- add 1 to last digit as a string (it cannot be 9...)
345 local function incd (n)
346 local s = string.format("%d", n)
347 s = string.gsub(s, "%d$", function (d)
348 assert(d ~= '9')
349 return string.char(string.byte(d) + 1)
350 end)
351 return s
352 end
353
354 -- 'tonumber' with overflow by 1
355 assert(eqT(tonumber(incd(maxint)), maxint + 1.0))
356 assert(eqT(tonumber(incd(minint)), minint - 1.0))
357
358 -- large numbers
359 assert(eqT(tonumber("1"..string.rep("0", 30)), 1e30))
360 assert(eqT(tonumber("-1"..string.rep("0", 30)), -1e30))
361
362 -- hexa format still wraps around
363 assert(eqT(tonumber("0x1"..string.rep("0", 30)), 0))
364
365 -- lexer in the limits
366 assert(minint == load("return " .. minint)())
367 assert(eqT(maxint, load("return " .. maxint)()))
368
369 assert(eqT(10000000000000000000000.0, 10000000000000000000000))
370 assert(eqT(-10000000000000000000000.0, -10000000000000000000000))
371end
372
373
374-- testing 'tonumber'
375
376-- 'tonumber' with numbers
377assert(tonumber(3.4) == 3.4)
378assert(eqT(tonumber(3), 3))
379assert(eqT(tonumber(maxint), maxint) and eqT(tonumber(minint), minint))
380assert(tonumber(1/0) == 1/0)
381
382-- 'tonumber' with strings
383assert(tonumber("0") == 0)
384assert(not tonumber(""))
385assert(not tonumber(" "))
386assert(not tonumber("-"))
387assert(not tonumber(" -0x "))
388assert(not tonumber{})
389assert(tonumber'+0.01' == 1/100 and tonumber'+.01' == 0.01 and
390 tonumber'.01' == 0.01 and tonumber'-1.' == -1 and
391 tonumber'+1.' == 1)
392assert(not tonumber'+ 0.01' and not tonumber'+.e1' and
393 not tonumber'1e' and not tonumber'1.0e+' and
394 not tonumber'.')
395assert(tonumber('-012') == -010-2)
396assert(tonumber('-1.2e2') == - - -120)
397
398assert(tonumber("0xffffffffffff") == (1 << (4*12)) - 1)
399assert(tonumber("0x"..string.rep("f", (intbits//4))) == -1)
400assert(tonumber("-0x"..string.rep("f", (intbits//4))) == 1)
401
402-- testing 'tonumber' with base
403assert(tonumber(' 001010 ', 2) == 10)
404assert(tonumber(' 001010 ', 10) == 001010)
405assert(tonumber(' -1010 ', 2) == -10)
406assert(tonumber('10', 36) == 36)
407assert(tonumber(' -10 ', 36) == -36)
408assert(tonumber(' +1Z ', 36) == 36 + 35)
409assert(tonumber(' -1z ', 36) == -36 + -35)
410assert(tonumber('-fFfa', 16) == -(10+(16*(15+(16*(15+(16*15)))))))
411assert(tonumber(string.rep('1', (intbits - 2)), 2) + 1 == 2^(intbits - 2))
412assert(tonumber('ffffFFFF', 16)+1 == (1 << 32))
413assert(tonumber('0ffffFFFF', 16)+1 == (1 << 32))
414assert(tonumber('-0ffffffFFFF', 16) - 1 == -(1 << 40))
415for i = 2,36 do
416 local i2 = i * i
417 local i10 = i2 * i2 * i2 * i2 * i2 -- i^10
418 assert(tonumber('\t10000000000\t', i) == i10)
419end
420
421if not _soft then
422 -- tests with very long numerals
423 assert(tonumber("0x"..string.rep("f", 13)..".0") == 2.0^(4*13) - 1)
424 assert(tonumber("0x"..string.rep("f", 150)..".0") == 2.0^(4*150) - 1)
425 assert(tonumber("0x"..string.rep("f", 300)..".0") == 2.0^(4*300) - 1)
426 assert(tonumber("0x"..string.rep("f", 500)..".0") == 2.0^(4*500) - 1)
427 assert(tonumber('0x3.' .. string.rep('0', 1000)) == 3)
428 assert(tonumber('0x' .. string.rep('0', 1000) .. 'a') == 10)
429 assert(tonumber('0x0.' .. string.rep('0', 13).."1") == 2.0^(-4*14))
430 assert(tonumber('0x0.' .. string.rep('0', 150).."1") == 2.0^(-4*151))
431 assert(tonumber('0x0.' .. string.rep('0', 300).."1") == 2.0^(-4*301))
432 assert(tonumber('0x0.' .. string.rep('0', 500).."1") == 2.0^(-4*501))
433
434 assert(tonumber('0xe03' .. string.rep('0', 1000) .. 'p-4000') == 3587.0)
435 assert(tonumber('0x.' .. string.rep('0', 1000) .. '74p4004') == 0x7.4)
436end
437
438-- testing 'tonumber' for invalid formats
439
440local function f (...)
441 if select('#', ...) == 1 then
442 return (...)
443 else
444 return "***"
445 end
446end
447
448assert(not f(tonumber('fFfa', 15)))
449assert(not f(tonumber('099', 8)))
450assert(not f(tonumber('1\0', 2)))
451assert(not f(tonumber('', 8)))
452assert(not f(tonumber(' ', 9)))
453assert(not f(tonumber(' ', 9)))
454assert(not f(tonumber('0xf', 10)))
455
456assert(not f(tonumber('inf')))
457assert(not f(tonumber(' INF ')))
458assert(not f(tonumber('Nan')))
459assert(not f(tonumber('nan')))
460
461assert(not f(tonumber(' ')))
462assert(not f(tonumber('')))
463assert(not f(tonumber('1 a')))
464assert(not f(tonumber('1 a', 2)))
465assert(not f(tonumber('1\0')))
466assert(not f(tonumber('1 \0')))
467assert(not f(tonumber('1\0 ')))
468assert(not f(tonumber('e1')))
469assert(not f(tonumber('e 1')))
470assert(not f(tonumber(' 3.4.5 ')))
471
472
473-- testing 'tonumber' for invalid hexadecimal formats
474
475assert(not tonumber('0x'))
476assert(not tonumber('x'))
477assert(not tonumber('x3'))
478assert(not tonumber('0x3.3.3')) -- two decimal points
479assert(not tonumber('00x2'))
480assert(not tonumber('0x 2'))
481assert(not tonumber('0 x2'))
482assert(not tonumber('23x'))
483assert(not tonumber('- 0xaa'))
484assert(not tonumber('-0xaaP ')) -- no exponent
485assert(not tonumber('0x0.51p'))
486assert(not tonumber('0x5p+-2'))
487
488
489-- testing hexadecimal numerals
490
491assert(0x10 == 16 and 0xfff == 2^12 - 1 and 0XFB == 251)
492assert(0x0p12 == 0 and 0x.0p-3 == 0)
493assert(0xFFFFFFFF == (1 << 32) - 1)
494assert(tonumber('+0x2') == 2)
495assert(tonumber('-0xaA') == -170)
496assert(tonumber('-0xffFFFfff') == -(1 << 32) + 1)
497
498-- possible confusion with decimal exponent
499assert(0E+1 == 0 and 0xE+1 == 15 and 0xe-1 == 13)
500
501
502-- floating hexas
503
504assert(tonumber(' 0x2.5 ') == 0x25/16)
505assert(tonumber(' -0x2.5 ') == -0x25/16)
506assert(tonumber(' +0x0.51p+8 ') == 0x51)
507assert(0x.FfffFFFF == 1 - '0x.00000001')
508assert('0xA.a' + 0 == 10 + 10/16)
509assert(0xa.aP4 == 0XAA)
510assert(0x4P-2 == 1)
511assert(0x1.1 == '0x1.' + '+0x.1')
512assert(0Xabcdef.0 == 0x.ABCDEFp+24)
513
514
515assert(1.1 == 1.+.1)
516assert(100.0 == 1E2 and .01 == 1e-2)
517assert(1111111111 - 1111111110 == 1000.00e-03)
518assert(1.1 == '1.'+'.1')
519assert(tonumber'1111111111' - tonumber'1111111110' ==
520 tonumber" +0.001e+3 \n\t")
521
522assert(0.1e-30 > 0.9E-31 and 0.9E30 < 0.1e31)
523
524assert(0.123456 > 0.123455)
525
526assert(tonumber('+1.23E18') == 1.23*10.0^18)
527
528-- testing order operators
529assert(not(1<1) and (1<2) and not(2<1))
530assert(not('a'<'a') and ('a'<'b') and not('b'<'a'))
531assert((1<=1) and (1<=2) and not(2<=1))
532assert(('a'<='a') and ('a'<='b') and not('b'<='a'))
533assert(not(1>1) and not(1>2) and (2>1))
534assert(not('a'>'a') and not('a'>'b') and ('b'>'a'))
535assert((1>=1) and not(1>=2) and (2>=1))
536assert(('a'>='a') and not('a'>='b') and ('b'>='a'))
537assert(1.3 < 1.4 and 1.3 <= 1.4 and not (1.3 < 1.3) and 1.3 <= 1.3)
538
539-- testing mod operator
540assert(eqT(-4 % 3, 2))
541assert(eqT(4 % -3, -2))
542assert(eqT(-4.0 % 3, 2.0))
543assert(eqT(4 % -3.0, -2.0))
544assert(eqT(4 % -5, -1))
545assert(eqT(4 % -5.0, -1.0))
546assert(eqT(4 % 5, 4))
547assert(eqT(4 % 5.0, 4.0))
548assert(eqT(-4 % -5, -4))
549assert(eqT(-4 % -5.0, -4.0))
550assert(eqT(-4 % 5, 1))
551assert(eqT(-4 % 5.0, 1.0))
552assert(eqT(4.25 % 4, 0.25))
553assert(eqT(10.0 % 2, 0.0))
554assert(eqT(-10.0 % 2, 0.0))
555assert(eqT(-10.0 % -2, 0.0))
556assert(math.pi - math.pi % 1 == 3)
557assert(math.pi - math.pi % 0.001 == 3.141)
558
559do -- very small numbers
560 local i, j = 0, 20000
561 while i < j do
562 local m = (i + j) // 2
563 if 10^-m > 0 then
564 i = m + 1
565 else
566 j = m
567 end
568 end
569 -- 'i' is the smallest possible ten-exponent
570 local b = 10^-(i - (i // 10)) -- a very small number
571 assert(b > 0 and b * b == 0)
572 local delta = b / 1000
573 assert(eq((2.1 * b) % (2 * b), (0.1 * b), delta))
574 assert(eq((-2.1 * b) % (2 * b), (2 * b) - (0.1 * b), delta))
575 assert(eq((2.1 * b) % (-2 * b), (0.1 * b) - (2 * b), delta))
576 assert(eq((-2.1 * b) % (-2 * b), (-0.1 * b), delta))
577end
578
579
580-- basic consistency between integer modulo and float modulo
581for i = -10, 10 do
582 for j = -10, 10 do
583 if j ~= 0 then
584 assert((i + 0.0) % j == i % j)
585 end
586 end
587end
588
589for i = 0, 10 do
590 for j = -10, 10 do
591 if j ~= 0 then
592 assert((2^i) % j == (1 << i) % j)
593 end
594 end
595end
596
597do -- precision of module for large numbers
598 local i = 10
599 while (1 << i) > 0 do
600 assert((1 << i) % 3 == i % 2 + 1)
601 i = i + 1
602 end
603
604 i = 10
605 while 2^i < math.huge do
606 assert(2^i % 3 == i % 2 + 1)
607 i = i + 1
608 end
609end
610
611assert(eqT(minint % minint, 0))
612assert(eqT(maxint % maxint, 0))
613assert((minint + 1) % minint == minint + 1)
614assert((maxint - 1) % maxint == maxint - 1)
615assert(minint % maxint == maxint - 1)
616
617assert(minint % -1 == 0)
618assert(minint % -2 == 0)
619assert(maxint % -2 == -1)
620
621-- non-portable tests because Windows C library cannot compute
622-- fmod(1, huge) correctly
623if not _port then
624 local function anan (x) assert(isNaN(x)) end -- assert Not a Number
625 anan(0.0 % 0)
626 anan(1.3 % 0)
627 anan(math.huge % 1)
628 anan(math.huge % 1e30)
629 anan(-math.huge % 1e30)
630 anan(-math.huge % -1e30)
631 assert(1 % math.huge == 1)
632 assert(1e30 % math.huge == 1e30)
633 assert(1e30 % -math.huge == -math.huge)
634 assert(-1 % math.huge == math.huge)
635 assert(-1 % -math.huge == -1)
636end
637
638
639-- testing unsigned comparisons
640assert(math.ult(3, 4))
641assert(not math.ult(4, 4))
642assert(math.ult(-2, -1))
643assert(math.ult(2, -1))
644assert(not math.ult(-2, -2))
645assert(math.ult(maxint, minint))
646assert(not math.ult(minint, maxint))
647
648
649assert(eq(math.sin(-9.8)^2 + math.cos(-9.8)^2, 1))
650assert(eq(math.tan(math.pi/4), 1))
651assert(eq(math.sin(math.pi/2), 1) and eq(math.cos(math.pi/2), 0))
652assert(eq(math.atan(1), math.pi/4) and eq(math.acos(0), math.pi/2) and
653 eq(math.asin(1), math.pi/2))
654assert(eq(math.deg(math.pi/2), 90) and eq(math.rad(90), math.pi/2))
655assert(math.abs(-10.43) == 10.43)
656assert(eqT(math.abs(minint), minint))
657assert(eqT(math.abs(maxint), maxint))
658assert(eqT(math.abs(-maxint), maxint))
659assert(eq(math.atan(1,0), math.pi/2))
660assert(math.fmod(10,3) == 1)
661assert(eq(math.sqrt(10)^2, 10))
662assert(eq(math.log(2, 10), math.log(2)/math.log(10)))
663assert(eq(math.log(2, 2), 1))
664assert(eq(math.log(9, 3), 2))
665assert(eq(math.exp(0), 1))
666assert(eq(math.sin(10), math.sin(10%(2*math.pi))))
667
668
669assert(tonumber(' 1.3e-2 ') == 1.3e-2)
670assert(tonumber(' -1.00000000000001 ') == -1.00000000000001)
671
672-- testing constant limits
673-- 2^23 = 8388608
674assert(8388609 + -8388609 == 0)
675assert(8388608 + -8388608 == 0)
676assert(8388607 + -8388607 == 0)
677
678
679
680do -- testing floor & ceil
681 assert(eqT(math.floor(3.4), 3))
682 assert(eqT(math.ceil(3.4), 4))
683 assert(eqT(math.floor(-3.4), -4))
684 assert(eqT(math.ceil(-3.4), -3))
685 assert(eqT(math.floor(maxint), maxint))
686 assert(eqT(math.ceil(maxint), maxint))
687 assert(eqT(math.floor(minint), minint))
688 assert(eqT(math.floor(minint + 0.0), minint))
689 assert(eqT(math.ceil(minint), minint))
690 assert(eqT(math.ceil(minint + 0.0), minint))
691 assert(math.floor(1e50) == 1e50)
692 assert(math.ceil(1e50) == 1e50)
693 assert(math.floor(-1e50) == -1e50)
694 assert(math.ceil(-1e50) == -1e50)
695 for _, p in pairs{31,32,63,64} do
696 assert(math.floor(2^p) == 2^p)
697 assert(math.floor(2^p + 0.5) == 2^p)
698 assert(math.ceil(2^p) == 2^p)
699 assert(math.ceil(2^p - 0.5) == 2^p)
700 end
701 checkerror("number expected", math.floor, {})
702 checkerror("number expected", math.ceil, print)
703 assert(eqT(math.tointeger(minint), minint))
704 assert(eqT(math.tointeger(minint .. ""), minint))
705 assert(eqT(math.tointeger(maxint), maxint))
706 assert(eqT(math.tointeger(maxint .. ""), maxint))
707 assert(eqT(math.tointeger(minint + 0.0), minint))
708 assert(not math.tointeger(0.0 - minint))
709 assert(not math.tointeger(math.pi))
710 assert(not math.tointeger(-math.pi))
711 assert(math.floor(math.huge) == math.huge)
712 assert(math.ceil(math.huge) == math.huge)
713 assert(not math.tointeger(math.huge))
714 assert(math.floor(-math.huge) == -math.huge)
715 assert(math.ceil(-math.huge) == -math.huge)
716 assert(not math.tointeger(-math.huge))
717 assert(math.tointeger("34.0") == 34)
718 assert(not math.tointeger("34.3"))
719 assert(not math.tointeger({}))
720 assert(not math.tointeger(0/0)) -- NaN
721end
722
723
724-- testing fmod for integers
725for i = -6, 6 do
726 for j = -6, 6 do
727 if j ~= 0 then
728 local mi = math.fmod(i, j)
729 local mf = math.fmod(i + 0.0, j)
730 assert(mi == mf)
731 assert(math.type(mi) == 'integer' and math.type(mf) == 'float')
732 if (i >= 0 and j >= 0) or (i <= 0 and j <= 0) or mi == 0 then
733 assert(eqT(mi, i % j))
734 end
735 end
736 end
737end
738assert(eqT(math.fmod(minint, minint), 0))
739assert(eqT(math.fmod(maxint, maxint), 0))
740assert(eqT(math.fmod(minint + 1, minint), minint + 1))
741assert(eqT(math.fmod(maxint - 1, maxint), maxint - 1))
742
743checkerror("zero", math.fmod, 3, 0)
744
745
746do -- testing max/min
747 checkerror("value expected", math.max)
748 checkerror("value expected", math.min)
749 assert(eqT(math.max(3), 3))
750 assert(eqT(math.max(3, 5, 9, 1), 9))
751 assert(math.max(maxint, 10e60) == 10e60)
752 assert(eqT(math.max(minint, minint + 1), minint + 1))
753 assert(eqT(math.min(3), 3))
754 assert(eqT(math.min(3, 5, 9, 1), 1))
755 assert(math.min(3.2, 5.9, -9.2, 1.1) == -9.2)
756 assert(math.min(1.9, 1.7, 1.72) == 1.7)
757 assert(math.min(-10e60, minint) == -10e60)
758 assert(eqT(math.min(maxint, maxint - 1), maxint - 1))
759 assert(eqT(math.min(maxint - 2, maxint, maxint - 1), maxint - 2))
760end
761-- testing implicit conversions
762
763local a,b = '10', '20'
764assert(a*b == 200 and a+b == 30 and a-b == -10 and a/b == 0.5 and -b == -20)
765assert(a == '10' and b == '20')
766
767
768do
769 print("testing -0 and NaN")
770 local mz <const> = -0.0
771 local z <const> = 0.0
772 assert(mz == z)
773 assert(1/mz < 0 and 0 < 1/z)
774 local a = {[mz] = 1}
775 assert(a[z] == 1 and a[mz] == 1)
776 a[z] = 2
777 assert(a[z] == 2 and a[mz] == 2)
778 local inf = math.huge * 2 + 1
779 local mz <const> = -1/inf
780 local z <const> = 1/inf
781 assert(mz == z)
782 assert(1/mz < 0 and 0 < 1/z)
783 local NaN <const> = inf - inf
784 assert(NaN ~= NaN)
785 assert(not (NaN < NaN))
786 assert(not (NaN <= NaN))
787 assert(not (NaN > NaN))
788 assert(not (NaN >= NaN))
789 assert(not (0 < NaN) and not (NaN < 0))
790 local NaN1 <const> = 0/0
791 assert(NaN ~= NaN1 and not (NaN <= NaN1) and not (NaN1 <= NaN))
792 local a = {}
793 assert(not pcall(rawset, a, NaN, 1))
794 assert(a[NaN] == undef)
795 a[1] = 1
796 assert(not pcall(rawset, a, NaN, 1))
797 assert(a[NaN] == undef)
798 -- strings with same binary representation as 0.0 (might create problems
799 -- for constant manipulation in the pre-compiler)
800 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"
801 assert(a1 == a2 and a2 == a4 and a1 ~= a3)
802 assert(a3 == a5)
803end
804
805
806print("testing 'math.random'")
807
808local random, max, min = math.random, math.max, math.min
809
810local function testnear (val, ref, tol)
811 return (math.abs(val - ref) < ref * tol)
812end
813
814
815-- low-level!! For the current implementation of random in Lua,
816-- the first call after seed 1007 should return 0x7a7040a5a323c9d6
817do
818 -- all computations should work with 32-bit integers
819 local h <const> = 0x7a7040a5 -- higher half
820 local l <const> = 0xa323c9d6 -- lower half
821
822 math.randomseed(1007)
823 -- get the low 'intbits' of the 64-bit expected result
824 local res = (h << 32 | l) & ~(~0 << intbits)
825 assert(random(0) == res)
826
827 math.randomseed(1007, 0)
828 -- using higher bits to generate random floats; (the '% 2^32' converts
829 -- 32-bit integers to floats as unsigned)
830 local res
831 if floatbits <= 32 then
832 -- get all bits from the higher half
833 res = (h >> (32 - floatbits)) % 2^32
834 else
835 -- get 32 bits from the higher half and the rest from the lower half
836 res = (h % 2^32) * 2^(floatbits - 32) + ((l >> (64 - floatbits)) % 2^32)
837 end
838 local rand = random()
839 assert(eq(rand, 0x0.7a7040a5a323c9d6, 2^-floatbits))
840 assert(rand * 2^floatbits == res)
841end
842
843do
844 -- testing return of 'randomseed'
845 local x, y = math.randomseed()
846 local res = math.random(0)
847 x, y = math.randomseed(x, y) -- should repeat the state
848 assert(math.random(0) == res)
849 math.randomseed(x, y) -- again should repeat the state
850 assert(math.random(0) == res)
851 -- keep the random seed for following tests
852 print(string.format("random seeds: %d, %d", x, y))
853end
854
855do -- test random for floats
856 local randbits = math.min(floatbits, 64) -- at most 64 random bits
857 local mult = 2^randbits -- to make random float into an integral
858 local counts = {} -- counts for bits
859 for i = 1, randbits do counts[i] = 0 end
860 local up = -math.huge
861 local low = math.huge
862 local rounds = 100 * randbits -- 100 times for each bit
863 local totalrounds = 0
864 ::doagain:: -- will repeat test until we get good statistics
865 for i = 0, rounds do
866 local t = random()
867 assert(0 <= t and t < 1)
868 up = max(up, t)
869 low = min(low, t)
870 assert(t * mult % 1 == 0) -- no extra bits
871 local bit = i % randbits -- bit to be tested
872 if (t * 2^bit) % 1 >= 0.5 then -- is bit set?
873 counts[bit + 1] = counts[bit + 1] + 1 -- increment its count
874 end
875 end
876 totalrounds = totalrounds + rounds
877 if not (eq(up, 1, 0.001) and eq(low, 0, 0.001)) then
878 goto doagain
879 end
880 -- all bit counts should be near 50%
881 local expected = (totalrounds / randbits / 2)
882 for i = 1, randbits do
883 if not testnear(counts[i], expected, 0.10) then
884 goto doagain
885 end
886 end
887 print(string.format("float random range in %d calls: [%f, %f]",
888 totalrounds, low, up))
889end
890
891
892do -- test random for full integers
893 local up = 0
894 local low = 0
895 local counts = {} -- counts for bits
896 for i = 1, intbits do counts[i] = 0 end
897 local rounds = 100 * intbits -- 100 times for each bit
898 local totalrounds = 0
899 ::doagain:: -- will repeat test until we get good statistics
900 for i = 0, rounds do
901 local t = random(0)
902 up = max(up, t)
903 low = min(low, t)
904 local bit = i % intbits -- bit to be tested
905 -- increment its count if it is set
906 counts[bit + 1] = counts[bit + 1] + ((t >> bit) & 1)
907 end
908 totalrounds = totalrounds + rounds
909 local lim = maxint >> 10
910 if not (maxint - up < lim and low - minint < lim) then
911 goto doagain
912 end
913 -- all bit counts should be near 50%
914 local expected = (totalrounds / intbits / 2)
915 for i = 1, intbits do
916 if not testnear(counts[i], expected, 0.10) then
917 goto doagain
918 end
919 end
920 print(string.format(
921 "integer random range in %d calls: [minint + %.0fppm, maxint - %.0fppm]",
922 totalrounds, (minint - low) / minint * 1e6,
923 (maxint - up) / maxint * 1e6))
924end
925
926do
927 -- test distribution for a dice
928 local count = {0, 0, 0, 0, 0, 0}
929 local rep = 200
930 local totalrep = 0
931 ::doagain::
932 for i = 1, rep * 6 do
933 local r = random(6)
934 count[r] = count[r] + 1
935 end
936 totalrep = totalrep + rep
937 for i = 1, 6 do
938 if not testnear(count[i], totalrep, 0.05) then
939 goto doagain
940 end
941 end
942end
943
944do
945 local function aux (x1, x2) -- test random for small intervals
946 local mark = {}; local count = 0 -- to check that all values appeared
947 while true do
948 local t = random(x1, x2)
949 assert(x1 <= t and t <= x2)
950 if not mark[t] then -- new value
951 mark[t] = true
952 count = count + 1
953 if count == x2 - x1 + 1 then -- all values appeared; OK
954 goto ok
955 end
956 end
957 end
958 ::ok::
959 end
960
961 aux(-10,0)
962 aux(1, 6)
963 aux(1, 2)
964 aux(1, 13)
965 aux(1, 31)
966 aux(1, 32)
967 aux(1, 33)
968 aux(-10, 10)
969 aux(-10,-10) -- unit set
970 aux(minint, minint) -- unit set
971 aux(maxint, maxint) -- unit set
972 aux(minint, minint + 9)
973 aux(maxint - 3, maxint)
974end
975
976do
977 local function aux(p1, p2) -- test random for large intervals
978 local max = minint
979 local min = maxint
980 local n = 100
981 local mark = {}; local count = 0 -- to count how many different values
982 ::doagain::
983 for _ = 1, n do
984 local t = random(p1, p2)
985 if not mark[t] then -- new value
986 assert(p1 <= t and t <= p2)
987 max = math.max(max, t)
988 min = math.min(min, t)
989 mark[t] = true
990 count = count + 1
991 end
992 end
993 -- at least 80% of values are different
994 if not (count >= n * 0.8) then
995 goto doagain
996 end
997 -- min and max not too far from formal min and max
998 local diff = (p2 - p1) >> 4
999 if not (min < p1 + diff and max > p2 - diff) then
1000 goto doagain
1001 end
1002 end
1003 aux(0, maxint)
1004 aux(1, maxint)
1005 aux(3, maxint // 3)
1006 aux(minint, -1)
1007 aux(minint // 2, maxint // 2)
1008 aux(minint, maxint)
1009 aux(minint + 1, maxint)
1010 aux(minint, maxint - 1)
1011 aux(0, 1 << (intbits - 5))
1012end
1013
1014
1015assert(not pcall(random, 1, 2, 3)) -- too many arguments
1016
1017-- empty interval
1018assert(not pcall(random, minint + 1, minint))
1019assert(not pcall(random, maxint, maxint - 1))
1020assert(not pcall(random, maxint, minint))
1021
1022
1023
1024print('OK')