[Bug #20705] Update strtod implementation

The absence of either the integer or fractional part should be
allowed.
This commit is contained in:
Nobuyoshi Nakada 2024-09-05 22:08:41 +09:00
parent f37e6d7f7b
commit d17edf3a17
No known key found for this signature in database
GPG Key ID: 3582D74E1FEE4465
Notes: git 2024-10-05 14:59:02 +00:00
3 changed files with 20 additions and 26 deletions

View File

@ -1552,7 +1552,7 @@ break2:
aadj = 1.0;
nd0 = -4;
if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0;
if (!*++s || (!(s1 = strchr(hexdigit, *s)) && *s != '.')) goto ret0;
if (*s == '0') {
while (*++s == '0');
if (!*s) goto ret;
@ -1566,9 +1566,7 @@ break2:
} while (*++s && (s1 = strchr(hexdigit, *s)));
}
if (*s == '.') {
dsign = 1;
if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0;
if ((*s == '.') && *++s && (s1 = strchr(hexdigit, *s))) {
if (nd0 < 0) {
while (*s == '0') {
s++;
@ -1583,9 +1581,6 @@ break2:
}
}
}
else {
dsign = 0;
}
if (*s == 'P' || *s == 'p') {
dsign = 0x2C - *++s; /* +: 2B, -: 2D */
@ -1608,9 +1603,6 @@ break2:
} while ('0' <= c && c <= '9');
nd0 += nd * dsign;
}
else {
if (dsign) goto ret0;
}
dval(rv) = ldexp(adj, nd0);
goto ret;
}
@ -1647,9 +1639,9 @@ break2:
}
#endif
if (c == '.') {
if (!ISDIGIT(s[1]))
goto dig_done;
c = *++s;
if (!ISDIGIT(c))
goto dig_done;
if (!nd) {
for (; c == '0'; c = *++s)
nz++;

View File

@ -749,6 +749,9 @@ describe "String#%" do
(format % "-10.4e-20").should == (format % -10.4e-20)
(format % ".5").should == (format % 0.5)
(format % "-.5").should == (format % -0.5)
ruby_bug("#20705", ""..."3.4") do
(format % "10.").should == (format % 10)
end
# Something's strange with this spec:
# it works just fine in individual mode, but not when run as part of a group
(format % "10_1_0.5_5_5").should == (format % 1010.555)
@ -758,7 +761,6 @@ describe "String#%" do
-> { format % "" }.should raise_error(ArgumentError)
-> { format % "x" }.should raise_error(ArgumentError)
-> { format % "." }.should raise_error(ArgumentError)
-> { format % "10." }.should raise_error(ArgumentError)
-> { format % "5x" }.should raise_error(ArgumentError)
-> { format % "0b1" }.should raise_error(ArgumentError)
-> { format % "10e10.5" }.should raise_error(ArgumentError)

View File

@ -129,9 +129,9 @@ class TestFloat < Test::Unit::TestCase
assert_in_delta(a, 0, Float::EPSILON)
a = Float("-.0")
assert_in_delta(a, 0, Float::EPSILON)
assert_raise(ArgumentError){Float("0.")}
assert_raise(ArgumentError){Float("+0.")}
assert_raise(ArgumentError){Float("-0.")}
assert_equal(0.0, Float("0."))
assert_equal(0.0, Float("+0."))
assert_equal(0.0, Float("-0."))
assert_raise(ArgumentError){Float(".")}
assert_raise(ArgumentError){Float("+")}
assert_raise(ArgumentError){Float("+.")}
@ -139,12 +139,12 @@ class TestFloat < Test::Unit::TestCase
assert_raise(ArgumentError){Float("-.")}
assert_raise(ArgumentError){Float("1e")}
assert_raise(ArgumentError){Float("1__1")}
assert_raise(ArgumentError){Float("1.")}
assert_raise(ArgumentError){Float("1.e+00")}
assert_raise(ArgumentError){Float("0x.1")}
assert_raise(ArgumentError){Float("0x1.")}
assert_raise(ArgumentError){Float("0x1.0")}
assert_raise(ArgumentError){Float("0x1.p+0")}
assert_equal(1.0, Float("1."))
assert_equal(1.0, Float("1.e+00"))
assert_equal(0.0625, Float("0x.1"))
assert_equal(1.0, Float("0x1."))
assert_equal(1.0, Float("0x1.0"))
assert_equal(1.0, Float("0x1.p+0"))
# add expected behaviour here.
assert_equal(10, Float("1_0"))
@ -191,7 +191,7 @@ class TestFloat < Test::Unit::TestCase
break
end
end
assert_nil(x, ->{"%a" % x})
assert_equal(1.0, x, ->{"%a" % x})
end
def test_divmod
@ -833,10 +833,10 @@ class TestFloat < Test::Unit::TestCase
assert_equal(15, Float('0xf'))
assert_equal(15, Float('0xfp0'))
assert_raise(ArgumentError) { Float('0xfp') }
assert_raise(ArgumentError) { Float('0xf.') }
assert_equal(15, Float('0xf.'))
assert_raise(ArgumentError) { Float('0xf.p') }
assert_raise(ArgumentError) { Float('0xf.p0') }
assert_raise(ArgumentError) { Float('0xf.f') }
assert_equal(15, Float('0xf.p0'))
assert_equal(15.9375, Float('0xf.f'))
assert_raise(ArgumentError) { Float('0xf.fp') }
begin
verbose_bak, $VERBOSE = $VERBOSE, nil