diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-08-28 12:36:58 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-08-28 12:36:58 -0300 |
| commit | 5382a22e0eea878339c504b2a9a3b36bcd839fcc (patch) | |
| tree | f4208ffe221d2f42920c751c3624f17d89b07079 /testes | |
| parent | 8c8a91f2ef7acccb99e3737913faad8d48b39571 (diff) | |
| download | lua-5382a22e0eea878339c504b2a9a3b36bcd839fcc.tar.gz lua-5382a22e0eea878339c504b2a9a3b36bcd839fcc.tar.bz2 lua-5382a22e0eea878339c504b2a9a3b36bcd839fcc.zip | |
Corrections in the implementation of '%' for floats.
The multiplication (m*b) used to test whether 'm' is non-zero and
'm' and 'b' have different signs can underflow for very small numbers,
giving a wrong result. The use of explicit comparisons solves this
problem. This commit also adds several new tests for '%' (both for
floats and for integers) to exercise more corner cases, such as
very large and very small values.
Diffstat (limited to 'testes')
| -rw-r--r-- | testes/math.lua | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/testes/math.lua b/testes/math.lua index 853dc20f..b387977e 100644 --- a/testes/math.lua +++ b/testes/math.lua | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | -- $Id: testes/math.lua $ | 1 | -- $Id: testes/math.lua 2018-07-25 15:31:04 -0300 $ |
| 2 | -- See Copyright Notice in file all.lua | 2 | -- See Copyright Notice in file all.lua |
| 3 | 3 | ||
| 4 | print("testing numbers and math lib") | 4 | print("testing numbers and math lib") |
| @@ -541,9 +541,73 @@ assert(eqT(-4 % 3, 2)) | |||
| 541 | assert(eqT(4 % -3, -2)) | 541 | assert(eqT(4 % -3, -2)) |
| 542 | assert(eqT(-4.0 % 3, 2.0)) | 542 | assert(eqT(-4.0 % 3, 2.0)) |
| 543 | assert(eqT(4 % -3.0, -2.0)) | 543 | assert(eqT(4 % -3.0, -2.0)) |
| 544 | assert(eqT(4 % -5, -1)) | ||
| 545 | assert(eqT(4 % -5.0, -1.0)) | ||
| 546 | assert(eqT(4 % 5, 4)) | ||
| 547 | assert(eqT(4 % 5.0, 4.0)) | ||
| 548 | assert(eqT(-4 % -5, -4)) | ||
| 549 | assert(eqT(-4 % -5.0, -4.0)) | ||
| 550 | assert(eqT(-4 % 5, 1)) | ||
| 551 | assert(eqT(-4 % 5.0, 1.0)) | ||
| 552 | assert(eqT(4.25 % 4, 0.25)) | ||
| 553 | assert(eqT(10.0 % 2, 0.0)) | ||
| 554 | assert(eqT(-10.0 % 2, 0.0)) | ||
| 555 | assert(eqT(-10.0 % -2, 0.0)) | ||
| 544 | assert(math.pi - math.pi % 1 == 3) | 556 | assert(math.pi - math.pi % 1 == 3) |
| 545 | assert(math.pi - math.pi % 0.001 == 3.141) | 557 | assert(math.pi - math.pi % 0.001 == 3.141) |
| 546 | 558 | ||
| 559 | do -- 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)) | ||
| 577 | end | ||
| 578 | |||
| 579 | |||
| 580 | -- basic consistency between integer modulo and float modulo | ||
| 581 | for 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 | ||
| 587 | end | ||
| 588 | |||
| 589 | for 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 | ||
| 595 | end | ||
| 596 | |||
| 597 | do -- 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 | ||
| 609 | end | ||
| 610 | |||
| 547 | assert(eqT(minint % minint, 0)) | 611 | assert(eqT(minint % minint, 0)) |
| 548 | assert(eqT(maxint % maxint, 0)) | 612 | assert(eqT(maxint % maxint, 0)) |
| 549 | assert((minint + 1) % minint == minint + 1) | 613 | assert((minint + 1) % minint == minint + 1) |
