lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi everyone, Lua-5.2 will have support for hexadecimal floats. Please, find attached a patch against Lua-5.1.4-4 [1] that adds hex floats to Lua-5.1. You can use "%A" or "%a" format specifier to string.format to serialize Lua number to its exact hexadecimal representation. You can also read it back from the floating point hex representation. sh$ lua Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio > =("%a"):format(1.0987654321e-20) 0x1.9f1a12718ed76p-67 > = 0x1.9f1a12718ed76p-67 1.0987654321e-20 > =tonumber("0x1.9f1a12718ed76p-67") 1.0987654321e-20 > --Leo-- [1] Lua-5.1.4-4 is the official Lua-5.1.4 release plus the patches found in http://www.lua.org/ftp/patch-lua-5.1.4-4 
From a787785fc03074d5dd49b0942cacea59b3d50a96 Mon Sep 17 00:00:00 2001 From: Leo Razoumov <LEOR@pionL2> Date: Fri, 11 Nov 2011 17:45:56 -0500 Subject: [Lua-5.1.4 patch] support for hexadecimal floats lua_Number (double) has no exact decimal representation because base_2 and base_10 are incompatible bases. As such, one cannot serialize lua_Number to decimal string and read it back without, in general, changing its value. To address the problem C99 as well as many modern libc representations support exact hexadecimal representation of floats in printf/scanf ("%a", "%A"), strtod functions. This patch adds support for hexadecimal floats to Lua lexer and to string.format function. Now Lua can serialize to strings and read back lua_Number(s) exactly. sh$ lua Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio > =("%a"):format(1.0987654321e-20) 0x1.9f1a12718ed76p-67 > = 0x1.9f1a12718ed76p-67 1.0987654321e-20 > =tonumber("0x1.9f1a12718ed76p-67") 1.0987654321e-20 > ************************************************************************ This patch is against Lua-5.1.4-4 which is the official Lua-5.1.4 release plus all the official patches contained in http://www.lua.org/ftp/patch-lua-5.1.4-4 To apply this patch issue sh$ cd /path/to/lua-5.1.4/distribution sh$ patch -p1 < hex-floats-lua-5.1.4-4.diff ************************************************************************ Signed-off-by: Leo Razoumov <LEOR@pionL2> --- src/llex.c | 18 +++++++++++++----- src/lstrlib.c | 3 +++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/llex.c b/src/llex.c index 88c6790..501a5d8 100644 --- a/src/llex.c +++ b/src/llex.c @@ -193,11 +193,19 @@ static void trydecpoint (LexState *ls, SemInfo *seminfo) { /* LUA_NUMBER */ static void read_numeral (LexState *ls, SemInfo *seminfo) { lua_assert(isdigit(ls->current)); - do { - save_and_next(ls); - } while (isdigit(ls->current) || ls->current == '.'); - if (check_next(ls, "Ee")) /* `E'? */ - check_next(ls, "+-"); /* optional exponent sign */ + if (check_next(ls, "0") && check_next(ls, "Xx")) {/* Hex int or float */ + do { + save_and_next(ls); + } while (isxdigit(ls->current) || ls->current == '.'); + if (check_next(ls, "Pp")) /* `P'? binary exponent */ + check_next(ls, "+-"); /* optional exponent sign */ + } else { /* Decimal int or float number */ + do { + save_and_next(ls); + } while (isdigit(ls->current) || ls->current == '.'); + if (check_next(ls, "Ee")) /* `E'? */ + check_next(ls, "+-"); /* optional exponent sign */ + } while (isalnum(ls->current) || ls->current == '_') save_and_next(ls); save(ls, '\0'); diff --git a/src/lstrlib.c b/src/lstrlib.c index 7a03489..95f812c 100644 --- a/src/lstrlib.c +++ b/src/lstrlib.c @@ -788,6 +788,9 @@ static int str_format (lua_State *L) { break; } case 'e': case 'E': case 'f': +#ifdef LUA_NUMBER_DOUBLE + case 'a': case 'A': +#endif case 'g': case 'G': { sprintf(buff, form, (double)luaL_checknumber(L, arg)); break; -- 1.7.4.5.LR1