Browse Source

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

They are basic for anything that handles the representation of
floating numbers.
Roberto I 3 weeks ago
parent
commit
53dc5a3bba
3 changed files with 46 additions and 17 deletions
  1. 16 16
      lmathlib.c
  2. 18 1
      manual/manual.of
  3. 12 0
      testes/math.lua

+ 16 - 16
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 */

+ 18 - 1
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]}.

+ 12 - 0
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)