diff options
Diffstat (limited to 'testes')
-rw-r--r-- | testes/math.lua | 106 |
1 files changed, 103 insertions, 3 deletions
diff --git a/testes/math.lua b/testes/math.lua index 0191f7dd..3937b9ce 100644 --- a/testes/math.lua +++ b/testes/math.lua | |||
@@ -22,6 +22,18 @@ do | |||
22 | end | 22 | end |
23 | end | 23 | end |
24 | 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 | |||
25 | local function isNaN (x) | 37 | local function isNaN (x) |
26 | return (x ~= x) | 38 | return (x ~= x) |
27 | end | 39 | end |
@@ -34,8 +46,8 @@ do | |||
34 | local x = 2.0^floatbits | 46 | local x = 2.0^floatbits |
35 | assert(x > x - 1.0 and x == x + 1.0) | 47 | assert(x > x - 1.0 and x == x + 1.0) |
36 | 48 | ||
37 | print(string.format("%d-bit integers, %d-bit (mantissa) floats", | 49 | local msg = " %d-bit integers, %d-bit*2^%d floats" |
38 | intbits, floatbits)) | 50 | print(string.format(msg, intbits, floatbits, maxexp)) |
39 | end | 51 | end |
40 | 52 | ||
41 | assert(math.type(0) == "integer" and math.type(0.0) == "float" | 53 | assert(math.type(0) == "integer" and math.type(0.0) == "float" |
@@ -803,7 +815,11 @@ do | |||
803 | end | 815 | end |
804 | 816 | ||
805 | 817 | ||
806 | print("testing 'math.random'") | 818 | -- |
819 | -- [[================================================================== | ||
820 | print("testing 'math.random'") | ||
821 | -- -=================================================================== | ||
822 | -- | ||
807 | 823 | ||
808 | local random, max, min = math.random, math.max, math.min | 824 | local random, max, min = math.random, math.max, math.min |
809 | 825 | ||
@@ -1019,6 +1035,90 @@ assert(not pcall(random, minint + 1, minint)) | |||
1019 | assert(not pcall(random, maxint, maxint - 1)) | 1035 | assert(not pcall(random, maxint, maxint - 1)) |
1020 | assert(not pcall(random, maxint, minint)) | 1036 | assert(not pcall(random, maxint, minint)) |
1021 | 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 | -- ]]================================================================== | ||
1022 | 1122 | ||
1023 | 1123 | ||
1024 | print('OK') | 1124 | print('OK') |