Functions 'frexp'-'ldexp' back to the math library

They are basic for anything that handles the representation of
floating numbers.
This commit is contained in:
Roberto I
2025-08-09 15:15:20 -03:00
parent 5b179eaf6a
commit 53dc5a3bba
3 changed files with 46 additions and 17 deletions

View File

@@ -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 */

View File

@@ -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]}.

View File

@@ -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)