Feature #2969: String#to_f e$B$,e(B -h.hhhe$B!^e(Bpd
e$B$r2r<a$G$-$k$h$&$Ke(B
http://redmine.ruby-lang.org/issues/show/2969
e$B5/I<<Te(B: Yui NARUSE
e$B%9%F!<%?%9e(B: Open, e$BM%@hEYe(B: Normal
C99 e$B$Ne(B printf e$B$K$Oe(B a e$B$H$$$&;XDj;R$,$"$j$^$9!#e(B
aA The argument is printed in style
e$B!Fe(B[-h.hhhe$B!^e(Bpd]e$B!Ge(B where there is
one digit before the hexadecimal point and the number
after
is equal to the precision specification for the
argument;
when the precision is missing, enough digits are
produced to
convey the argument’s exact double-precision
floating-point
representation. The values e$B!ge(B and NaN are
printed as e$B!Fe(Binfe$B!Ge(B
and e$B!Fe(Bnane$B!Ge(B, respectively.
e$B$3$l$r;H$&$H!"0J2<$N$h$&$J7A$G@07A$5$l$^$9!#e(B
-0.0 #=> “-0x0p+0”
729.0/10 #=> “0x1.239999999999ap+6”
Math.log(3) #=> “0x1.193ea7aad030ap+0”
Math.exp(100) #=> “0x1.3494a9b171bf5p+144”
e$B$3$N7A<0$NMxE@$O!"J#;($JIbF0>.?tE@?t$rHf3SE*>/$J$$J8;z?t$G@53N$KI=$;$k$3$H$H!“e(B
e$B2>?tIt$,e(B16e$B?J$G$”$k$?$a4]$a$,5/$-$F$$$k$3$H$r@bL@$9$k:]$KJXMx$JE@$,5s$2$i$l$^$9!#e(B
e$B$G!"$3$N7A<0$r;H$C$F$$$k$N$G$9$,!"e(BRubye$B$Ne(BString#to_f
e$B$G2r<a$7$F$/$l$:Ha$7$/$J$k$N$G!"e(B
e$B2r<a$G$-$k$h$&$K$7$^$;$s$+!#e(B
e$B%Q%C%A$O0J2<$NDL$j$G$9!#e(B
diff --git a/util.c b/util.c
index 5ebc5f3…e361d51 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') {
-
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 = 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)
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 64205f6…72d3242 100644
— a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -1381,10 +1381,24 @@ class TestString < Test::Unit::TestCase
end
def test_to_f
- assert_equal(0.0, S(“0.0”).to_f)
- assert_equal(?0, S(“0.0”).to_f.to_s[0])
- assert_equal(-0.0, S(“-0.0”).to_f)
- assert_equal(?-, S(“-0.0”).to_f.to_s[0])
assert_equal(344.3, S(“344.3”).to_f)
assert_equal(5.9742e24, S(“5.9742e24”).to_f)
assert_equal(98.6, S(“98.6 degrees”).to_f)
assert_equal(0.0, S(“degrees 100.0”).to_f) - assert_equal(0.0, S(“0x0p+0”).to_f)
- assert_equal(?0, S(“0x0p+0”).to_f.to_s[0])
- assert_equal(-0.0, S(“-0x0p+0”).to_f)
- assert_equal(?-, S(“-0x0p+0”).to_f.to_s[0])
- assert_equal(1.0, S(“0x1p+0”).to_f)
- assert_equal(?1, S(“0x1p+0”).to_f.to_s[0])
- assert_equal(1024.0, S(“0x1p+10”).to_f)
- assert_equal(0.0009765625, S(“0x1p-10”).to_f)
- assert_equal(2.6881171418161356e+43,
S(“0x1.3494a9b171bf5p+144”).to_f) - assert_equal(-3.720075976020836e-44,
S(“-0x1.a8c1f14e2af5dp-145”).to_f)
end
def test_to_i