diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-04-11 15:30:08 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-04-11 15:30:08 -0300 |
| commit | 69b5f7a410fab2a8a661e609a7286aea511479bb (patch) | |
| tree | 57d60738f4accedce310e2f45a3b492c64ff2048 | |
| parent | ae76c39712852d14514f9ef19ac332e961749d93 (diff) | |
| download | lua-69b5f7a410fab2a8a661e609a7286aea511479bb.tar.gz lua-69b5f7a410fab2a8a661e609a7286aea511479bb.tar.bz2 lua-69b5f7a410fab2a8a661e609a7286aea511479bb.zip | |
some details in 'luaO_int2fb' + more consistent use of the locale
decimal point
| -rw-r--r-- | lobject.c | 30 |
1 files changed, 20 insertions, 10 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 2.102 2015/02/05 17:15:33 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 2.103 2015/03/28 19:14:47 roberto Exp roberto $ |
| 3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -10,6 +10,7 @@ | |||
| 10 | #include "lprefix.h" | 10 | #include "lprefix.h" |
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | #include <locale.h> | ||
| 13 | #include <math.h> | 14 | #include <math.h> |
| 14 | #include <stdarg.h> | 15 | #include <stdarg.h> |
| 15 | #include <stdio.h> | 16 | #include <stdio.h> |
| @@ -40,8 +41,12 @@ LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT}; | |||
| 40 | int luaO_int2fb (unsigned int x) { | 41 | int luaO_int2fb (unsigned int x) { |
| 41 | int e = 0; /* exponent */ | 42 | int e = 0; /* exponent */ |
| 42 | if (x < 8) return x; | 43 | if (x < 8) return x; |
| 43 | while (x >= 0x10) { | 44 | while (x >= (8 << 4)) { /* coarse steps */ |
| 44 | x = (x+1) >> 1; | 45 | x = (x + 0xf) >> 4; /* x = ceil(x / 16) */ |
| 46 | e += 4; | ||
| 47 | } | ||
| 48 | while (x >= (8 << 1)) { /* fine steps */ | ||
| 49 | x = (x + 1) >> 1; /* x = ceil(x / 2) */ | ||
| 45 | e++; | 50 | e++; |
| 46 | } | 51 | } |
| 47 | return ((e+1) << 3) | (cast_int(x) - 8); | 52 | return ((e+1) << 3) | (cast_int(x) - 8); |
| @@ -56,8 +61,11 @@ int luaO_fb2int (int x) { | |||
| 56 | } | 61 | } |
| 57 | 62 | ||
| 58 | 63 | ||
| 64 | /* | ||
| 65 | ** Computes ceil(log2(x)) | ||
| 66 | */ | ||
| 59 | int luaO_ceillog2 (unsigned int x) { | 67 | int luaO_ceillog2 (unsigned int x) { |
| 60 | static const lu_byte log_2[256] = { | 68 | static const lu_byte log_2[256] = { /* log_2[i] = ceil(log2(i - 1)) */ |
| 61 | 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, | 69 | 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, |
| 62 | 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, | 70 | 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, |
| 63 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, | 71 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, |
| @@ -173,6 +181,7 @@ static int isneg (const char **s) { | |||
| 173 | ** Lua's implementation for 'lua_strx2number' | 181 | ** Lua's implementation for 'lua_strx2number' |
| 174 | ** =================================================================== | 182 | ** =================================================================== |
| 175 | */ | 183 | */ |
| 184 | |||
| 176 | #if !defined(lua_strx2number) | 185 | #if !defined(lua_strx2number) |
| 177 | 186 | ||
| 178 | /* maximum number of significant digits to read (to avoid overflows | 187 | /* maximum number of significant digits to read (to avoid overflows |
| @@ -184,21 +193,22 @@ static int isneg (const char **s) { | |||
| 184 | ** C99 specification for 'strtod' | 193 | ** C99 specification for 'strtod' |
| 185 | */ | 194 | */ |
| 186 | static lua_Number lua_strx2number (const char *s, char **endptr) { | 195 | static lua_Number lua_strx2number (const char *s, char **endptr) { |
| 196 | int dot = lua_getlocaledecpoint(); | ||
| 187 | lua_Number r = 0.0; /* result (accumulator) */ | 197 | lua_Number r = 0.0; /* result (accumulator) */ |
| 188 | int sigdig = 0; /* number of significant digits */ | 198 | int sigdig = 0; /* number of significant digits */ |
| 189 | int nosigdig = 0; /* number of non-significant digits */ | 199 | int nosigdig = 0; /* number of non-significant digits */ |
| 190 | int e = 0; /* exponent correction */ | 200 | int e = 0; /* exponent correction */ |
| 191 | int neg; /* 1 if number is negative */ | 201 | int neg; /* 1 if number is negative */ |
| 192 | int dot = 0; /* true after seen a dot */ | 202 | int hasdot = 0; /* true after seen a dot */ |
| 193 | *endptr = cast(char *, s); /* nothing is valid yet */ | 203 | *endptr = cast(char *, s); /* nothing is valid yet */ |
| 194 | while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ | 204 | while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ |
| 195 | neg = isneg(&s); /* check signal */ | 205 | neg = isneg(&s); /* check signal */ |
| 196 | if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ | 206 | if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ |
| 197 | return 0.0; /* invalid format (no '0x') */ | 207 | return 0.0; /* invalid format (no '0x') */ |
| 198 | for (s += 2; ; s++) { /* skip '0x' and read numeral */ | 208 | for (s += 2; ; s++) { /* skip '0x' and read numeral */ |
| 199 | if (*s == '.') { | 209 | if (*s == dot) { |
| 200 | if (dot) break; /* second dot? stop loop */ | 210 | if (hasdot) break; /* second dot? stop loop */ |
| 201 | else dot = 1; | 211 | else hasdot = 1; |
| 202 | } | 212 | } |
| 203 | else if (lisxdigit(cast_uchar(*s))) { | 213 | else if (lisxdigit(cast_uchar(*s))) { |
| 204 | if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */ | 214 | if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */ |
| @@ -206,7 +216,7 @@ static lua_Number lua_strx2number (const char *s, char **endptr) { | |||
| 206 | else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */ | 216 | else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */ |
| 207 | r = (r * cast_num(16.0)) + luaO_hexavalue(*s); | 217 | r = (r * cast_num(16.0)) + luaO_hexavalue(*s); |
| 208 | else e++; /* too many digits; ignore, but still count for exponent */ | 218 | else e++; /* too many digits; ignore, but still count for exponent */ |
| 209 | if (dot) e--; /* decimal digit? correct exponent */ | 219 | if (hasdot) e--; /* decimal digit? correct exponent */ |
| 210 | } | 220 | } |
| 211 | else break; /* neither a dot nor a digit */ | 221 | else break; /* neither a dot nor a digit */ |
| 212 | } | 222 | } |
| @@ -328,7 +338,7 @@ void luaO_tostring (lua_State *L, StkId obj) { | |||
| 328 | len = lua_number2str(buff, fltvalue(obj)); | 338 | len = lua_number2str(buff, fltvalue(obj)); |
| 329 | #if !defined(LUA_COMPAT_FLOATSTRING) | 339 | #if !defined(LUA_COMPAT_FLOATSTRING) |
| 330 | if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */ | 340 | if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */ |
| 331 | buff[len++] = '.'; | 341 | buff[len++] = lua_getlocaledecpoint(); |
| 332 | buff[len++] = '0'; /* adds '.0' to result */ | 342 | buff[len++] = '0'; /* adds '.0' to result */ |
| 333 | } | 343 | } |
| 334 | #endif | 344 | #endif |
