From 53dc5a3bbadac166a8b40904790f91b351e55dd9 Mon Sep 17 00:00:00 2001 From: Roberto I Date: Sat, 9 Aug 2025 15:15:20 -0300 Subject: Functions 'frexp'-'ldexp' back to the math library They are basic for anything that handles the representation of floating numbers. --- lmathlib.c | 32 ++++++++++++++++---------------- manual/manual.of | 19 ++++++++++++++++++- testes/math.lua | 12 ++++++++++++ 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/lmathlib.c b/lmathlib.c index bd34c888..b030f97e 100644 --- a/lmathlib.c +++ b/lmathlib.c @@ -203,6 +203,20 @@ static int math_rad (lua_State *L) { return 1; } +static int math_frexp (lua_State *L) { + int e; + lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); + lua_pushinteger(L, e); + return 2; +} + +static int math_ldexp (lua_State *L) { + lua_Number x = luaL_checknumber(L, 1); + int ep = (int)luaL_checkinteger(L, 2); + lua_pushnumber(L, l_mathop(ldexp)(x, ep)); + return 1; +} + static int math_min (lua_State *L) { int n = lua_gettop(L); /* number of arguments */ @@ -666,20 +680,6 @@ static int math_pow (lua_State *L) { return 1; } -static int math_frexp (lua_State *L) { - int e; - lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); - lua_pushinteger(L, e); - return 2; -} - -static int math_ldexp (lua_State *L) { - lua_Number x = luaL_checknumber(L, 1); - int ep = (int)luaL_checkinteger(L, 2); - lua_pushnumber(L, l_mathop(ldexp)(x, ep)); - return 1; -} - static int math_log10 (lua_State *L) { lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); return 1; @@ -702,7 +702,9 @@ static const luaL_Reg mathlib[] = { {"tointeger", math_toint}, {"floor", math_floor}, {"fmod", math_fmod}, + {"frexp", math_frexp}, {"ult", math_ult}, + {"ldexp", math_ldexp}, {"log", math_log}, {"max", math_max}, {"min", math_min}, @@ -718,8 +720,6 @@ static const luaL_Reg mathlib[] = { {"sinh", math_sinh}, {"tanh", math_tanh}, {"pow", math_pow}, - {"frexp", math_frexp}, - {"ldexp", math_ldexp}, {"log10", math_log10}, #endif /* placeholders */ diff --git a/manual/manual.of b/manual/manual.of index 61dd42f2..89e9b8f4 100644 --- a/manual/manual.of +++ b/manual/manual.of @@ -8341,6 +8341,17 @@ that rounds the quotient towards zero. (integer/float) } +@LibEntry{math.frexp (x)| + +Returns two numbers @id{m} and @id{e} such that @M{x = m2@sp{e}}, +where @id{e} is an integer. +When @id{x} is zero, NaN, +inf, or -inf, +@id{m} is equal to @id{x}; +otherwise, the absolute value of @id{m} +is in the range @C{(} @M{[0.5, 1)} @C{]}. + +} + @LibEntry{math.huge| The float value @idx{HUGE_VAL}, @@ -8348,6 +8359,12 @@ a value greater than any other numeric value. } +@LibEntry{math.ldexp(m, e)| + +Returns @M{m2@sp{e}}, where @id{e} is an integer. + +} + @LibEntry{math.log (x [, base])| Returns the logarithm of @id{x} in the given base. @@ -8403,7 +8420,7 @@ Converts the angle @id{x} from degrees to radians. When called without arguments, returns a pseudo-random float with uniform distribution -in the range @C{(} @M{[0,1)}. @C{]} +in the range @C{(} @M{[0, 1)}. @C{]} When called with two integers @id{m} and @id{n}, @id{math.random} returns a pseudo-random integer with uniform distribution in the range @M{[m, n]}. diff --git a/testes/math.lua b/testes/math.lua index 0d228d09..54d19c40 100644 --- a/testes/math.lua +++ b/testes/math.lua @@ -685,6 +685,18 @@ assert(eq(math.exp(0), 1)) assert(eq(math.sin(10), math.sin(10%(2*math.pi)))) +do print("testing ldexp/frexp") + global ipairs + for _, x in ipairs{0, 10, 32, -math.pi, 1e10, 1e-10, math.huge, -math.huge} do + local m, p = math.frexp(x) + assert(math.ldexp(m, p) == x) + local am = math.abs(m) + assert(m == x or (0.5 <= am and am < 1)) + end + +end + + assert(tonumber(' 1.3e-2 ') == 1.3e-2) assert(tonumber(' -1.00000000000001 ') == -1.00000000000001) -- cgit v1.2.3-55-g6feb