diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-03-17 16:21:45 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-03-17 16:21:45 +0000 |
commit | 9eb68d7c44a5c19396b3bc7123d3828bb7ae1b39 (patch) | |
tree | bc158c02daea97e3d58e70d5a010edbf6cb4ef21 /util.c | |
parent | 5f0be51c21b3fe699c7fd6929e74ca9ade9a4339 (diff) | |
download | ruby-9eb68d7c44a5c19396b3bc7123d3828bb7ae1b39.tar.gz |
* util.c (ruby_strtod): Add support for Hexadecimal
floating-point expression [ruby-dev:40650] #2969
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26965 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 38 |
1 files changed, 38 insertions, 0 deletions
@@ -2106,6 +2106,44 @@ ruby_strtod(const char *s00, char **se) } break2: if (*s == '0') { + if (s[1] == 'x' || s[1] == 'X') { + static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF"; + s0 = ++s; + adj = 0; + + while (*++s && (s1 = strchr(hexdigit, *s))) { + adj *= 16; + adj += (s1 - hexdigit) & 15; + } + + if (*s == '.') { + aadj = 1.; + while (*++s && (s1 = strchr(hexdigit, *s))) { + aadj /= 16; + adj += aadj * ((s1 - hexdigit) & 15); + } + } + + if (*s != 'P' && *s != 'p') { + s = s0; + goto ret; + } + + dsign = 0x2C - *++s; /* +: 2B, -: 2D */ + if (abs(dsign) != 1) { + s = s0; + goto ret; + } + + for (nd = 0, s++; (c = *s) >= '0' && c <= '9'; s++) { + nd *= 10; + nd += c; + nd -= '0'; + } + + dval(rv) = ldexp(adj, nd * dsign); + goto ret; + } nz0 = 1; while (*++s == '0') ; if (!*s) |