summaryrefslogtreecommitdiff
path: root/util.c
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-03-17 16:21:45 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-03-17 16:21:45 +0000
commit9eb68d7c44a5c19396b3bc7123d3828bb7ae1b39 (patch)
treebc158c02daea97e3d58e70d5a010edbf6cb4ef21 /util.c
parent5f0be51c21b3fe699c7fd6929e74ca9ade9a4339 (diff)
* 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.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/util.c b/util.c
index 5ebc5f3e87..9cdb563040 100644
--- a/util.c
+++ b/util.c
@@ -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)