Last active
August 20, 2021 22:13
-
-
Save CaptainPRICE/342303bba104354257db0471bf996bd3 to your computer and use it in GitHub Desktop.
math.finite, math.isinf & math.isnan functions in pure Lua. Completely covered (all tests passed). https://i.imgur.com/1vzo2x9.png
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local NAN = 0.0 / 0.0 | |
local NINF = -math.huge | |
local PINF = math.huge | |
--- Returns true if given value is a finite number; otherwise false or nil if value is not of type string nor number. | |
function math.finite(value) | |
if type(value) == "string" then | |
value = tonumber(value) | |
if value == nil then return nil end | |
elseif type(value) ~= "number" then | |
return nil | |
end | |
return value > NINF and value < PINF | |
end | |
--- Returns 1 if given value is a positive infinity or -1 if given value is a negative infinity; otherwise 0 or nil if value is not of type string nor number. | |
function math.isinf(value) | |
if type(value) == "string" then | |
value = tonumber(value) | |
if value == nil then return nil end | |
elseif type(value) ~= "number" then | |
return nil | |
end | |
if value == PINF then return 1 end | |
if value == NINF then return -1 end | |
return 0 | |
end | |
--- Returns true if given value is not a number (NaN); otherwise false or nil if value is not of type string nor number. | |
function math.isnan(value) | |
if type(value) == "string" then | |
value = tonumber(value) | |
if value == nil then return nil end | |
elseif type(value) ~= "number" then | |
return nil | |
end | |
return value ~= value | |
end | |
-- | |
-- Unit tests. | |
-- | |
local tests_index = { | |
"Finite_1", | |
"Finite_2", | |
"Finite_3", | |
"Finite_4", | |
"Finite_5", | |
"Finite_6", | |
"Infinity_1", | |
"Infinity_2", | |
"Infinity_3", | |
"Infinity_4", | |
"Infinity_5", | |
"Infinity_6", | |
"NaN_1", | |
"NaN_2", | |
"NaN_3", | |
"NaN_4", | |
"NaN_5", | |
"NaN_6", | |
} | |
local tests = { | |
Finite_1 = function() return math.finite(PINF) == false end, | |
Finite_2 = function() return math.finite(NINF) == false end, | |
Finite_3 = function() return math.finite(NAN) == false end, | |
Finite_4 = function() return math.finite(math.random(10000000000000.0, 10000000000000.0)) == true end, | |
Finite_5 = function() return math.finite("invalid number") == nil end, | |
Finite_6 = function() return math.finite("123456789") == true end, | |
Infinity_1 = function() return math.isinf(PINF) == 1 end, | |
Infinity_2 = function() return math.isinf(NINF) == -1 end, | |
Infinity_3 = function() return math.isinf(NAN) == 0 end, | |
Infinity_4 = function() return math.isinf(math.random(10000000000000.0, 10000000000000.0)) == 0 end, | |
Infinity_5 = function() return math.isinf("invalid number") == nil end, | |
Infinity_6 = function() return math.isinf("123456789") == 0 end, | |
NaN_1 = function() return math.isnan(PINF) == false end, | |
NaN_2 = function() return math.isnan(NINF) == false end, | |
NaN_3 = function() return math.isnan(NAN) == true end, | |
NaN_4 = function() return math.isnan(math.random(10000000000000.0, 10000000000000.0)) == false end, | |
NaN_5 = function() return math.isnan("invalid number") == nil end, | |
NaN_6 = function() return math.isnan("123456789") == false end, | |
} | |
local pass_count, fail_count, total_count = 0, 0, 0 | |
for _, test_name in ipairs(tests_index) do | |
local test_func = tests[test_name] | |
total_count = total_count + 1 | |
test_name = test_name:gsub("_", " ") | |
local test_result = test_func() | |
if test_result then | |
pass_count = pass_count + 1 | |
else | |
fail_count = fail_count + 1 | |
end | |
local test_result_text = test_result and "Test passed." or "Test FAILED!!!" | |
print("[" .. os.date("%d-%m-%Y %H:%M:%S") .. "] [" .. ("%0" .. tostring(#tests_index):len() .. ".0f"):format(total_count) .. "] " .. test_name .. ": " .. test_result_text) | |
end | |
print("-----------------------------------") | |
print("Total: " .. total_count .. " tests.") | |
print("Passed: " .. pass_count .. " / " .. total_count .. " (" .. ("%.2f"):format((pass_count / total_count) * 100.0) .. "% covered).") | |
print("Failed: " .. fail_count .. " / " .. total_count .. " (" .. ("%.2f"):format((fail_count / total_count) * 100.0) .. "% not covered).") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment