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