mirror of https://github.com/lua/lua
official support for floating hexa numerals
This commit is contained in:
parent
1aead7f553
commit
af119c8b55
87
lobject.c
87
lobject.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lobject.c,v 2.43 2010/10/29 15:54:55 roberto Exp roberto $
|
||||
** $Id: lobject.c,v 2.44 2010/12/06 21:08:36 roberto Exp roberto $
|
||||
** Some generic functions over Lua objects
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -106,20 +106,87 @@ lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
|
|||
}
|
||||
|
||||
|
||||
static int checkend (const char *s, const char *e, const char *endptr) {
|
||||
if (endptr == s) return 0; /* no characters converted */
|
||||
while (lisspace(cast(unsigned char, *endptr))) endptr++;
|
||||
return (endptr == e); /* OK if no trailing characters */
|
||||
int luaO_hexavalue (int c) {
|
||||
if (lisdigit(c)) return c - '0';
|
||||
else if (lisupper(c)) return c - 'A' + 10;
|
||||
else return c - 'a' + 10;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(lua_strx2number)
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
static int isneg (const char **s) {
|
||||
if (**s == '-') { (*s)++; return 1; }
|
||||
else if (**s == '+') (*s)++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static lua_Number readhexa (const char **s, lua_Number r, int *count) {
|
||||
while (lisxdigit(cast_uchar(**s))) { /* read integer part */
|
||||
r = (r * 16.0) + (double)luaO_hexavalue(*(*s)++);
|
||||
(*count)++;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** convert an hexadecimal numeric string to a number, following
|
||||
** C99 specification for 'strtod'
|
||||
*/
|
||||
static lua_Number lua_strx2number (const char *s, char **endptr) {
|
||||
lua_Number r = 0.0;
|
||||
int e = 0, i = 0;
|
||||
int neg = 0; /* 1 if number is negative */
|
||||
*endptr = cast(char *, s); /* nothing is valid yet */
|
||||
while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
|
||||
neg = isneg(&s); /* check signal */
|
||||
if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
|
||||
return 0.0; /* invalid format (no '0x') */
|
||||
s += 2; /* skip '0x' */
|
||||
r = readhexa(&s, r, &i); /* read integer part */
|
||||
if (*s == '.') {
|
||||
s++; /* skip dot */
|
||||
r = readhexa(&s, r, &e); /* read fractional part */
|
||||
}
|
||||
if (i == 0 && e == 0)
|
||||
return 0.0; /* invalid format (no digit) */
|
||||
e *= -4; /* each fractional digit divides value by 2^-4 */
|
||||
*endptr = cast(char *, s); /* valid up to here */
|
||||
if (*s == 'p' || *s == 'P') { /* exponent part? */
|
||||
int exp1 = 0;
|
||||
int neg1;
|
||||
s++; /* skip 'p' */
|
||||
neg1 = isneg(&s); /* signal */
|
||||
if (!lisdigit(cast_uchar(*s)))
|
||||
goto ret; /* must have at least one digit */
|
||||
while (lisdigit(cast_uchar(*s))) /* read exponent */
|
||||
exp1 = exp1 * 10 + *(s++) - '0';
|
||||
if (neg1) exp1 = -exp1;
|
||||
e += exp1;
|
||||
}
|
||||
*endptr = cast(char *, s); /* valid up to here */
|
||||
ret:
|
||||
if (neg) r = -r;
|
||||
return ldexp(r, e);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int luaO_str2d (const char *s, size_t len, lua_Number *result) {
|
||||
char *endptr;
|
||||
const char *e = s + len; /* string 's' ends here */
|
||||
*result = lua_str2number(s, &endptr);
|
||||
if (checkend(s, e, endptr)) return 1; /* conversion OK? */
|
||||
*result = cast_num(strtoul(s, &endptr, 0)); /* try hexadecimal */
|
||||
return checkend(s, e, endptr);
|
||||
if (strpbrk(s, "xX")) /* hexa? */
|
||||
*result = lua_strx2number(s, &endptr);
|
||||
else
|
||||
*result = lua_str2number(s, &endptr);
|
||||
if (endptr == s) return 0; /* nothing recognized */
|
||||
while (lisspace(cast_uchar(*endptr))) endptr++;
|
||||
return (endptr == s + len); /* OK if no trailing characters */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lstrlib.c,v 1.158 2010/11/16 20:39:41 roberto Exp roberto $
|
||||
** $Id: lstrlib.c,v 1.159 2010/11/19 16:25:51 roberto Exp roberto $
|
||||
** Standard library for string operations and pattern-matching
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -861,6 +861,9 @@ static int str_format (lua_State *L) {
|
|||
break;
|
||||
}
|
||||
case 'e': case 'E': case 'f':
|
||||
#if defined(LUA_USE_AFORMAT)
|
||||
case 'a': case 'A':
|
||||
#endif
|
||||
case 'g': case 'G': {
|
||||
addlenmod(form, LUA_FLTFRMLEN);
|
||||
nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg));
|
||||
|
|
20
luaconf.h
20
luaconf.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: luaconf.h,v 1.151 2010/11/12 15:48:30 roberto Exp roberto $
|
||||
** $Id: luaconf.h,v 1.152 2010/12/08 12:58:04 roberto Exp roberto $
|
||||
** Configuration file for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -35,6 +35,7 @@
|
|||
|
||||
#if defined(LUA_WIN)
|
||||
#define LUA_DL_DLL
|
||||
#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -43,6 +44,8 @@
|
|||
#define LUA_USE_POSIX
|
||||
#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
|
||||
#define LUA_USE_READLINE /* needs some extra libraries */
|
||||
#define LUA_USE_HEXAFLOAT /* assume 'strtod' handles hexa formats */
|
||||
#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
|
||||
#endif
|
||||
|
||||
#if defined(LUA_USE_MACOSX)
|
||||
|
@ -377,14 +380,27 @@
|
|||
@@ LUA_NUMBER_FMT is the format for writing numbers.
|
||||
@@ lua_number2str converts a number to a string.
|
||||
@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
|
||||
@@ lua_str2number converts a string to a number.
|
||||
*/
|
||||
#define LUA_NUMBER_SCAN "%lf"
|
||||
#define LUA_NUMBER_FMT "%.14g"
|
||||
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
|
||||
#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
|
||||
|
||||
|
||||
/*
|
||||
@@ lua_str2number converts a decimal numeric string to a number.
|
||||
@@ lua_strx2number converts an hexadecimal numeric string to a number.
|
||||
** In C99, 'strtod' do both conversions. C89, however, has no function
|
||||
** to convert floating hexadecimal strings to numbers. For these
|
||||
** systems, you can leave 'lua_strx2number' undefined and Lua will
|
||||
** provide its own implementation.
|
||||
*/
|
||||
#define lua_str2number(s,p) strtod((s), (p))
|
||||
|
||||
#if defined(LUA_USE_HEXAFLOAT)
|
||||
#define lua_strx2number(s,p) strtod((s), (p))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ The luai_num* macros define the primitive operations over numbers.
|
||||
|
|
Loading…
Reference in New Issue