mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* util.c (ruby_strtod): get rid of overflow/underflow as possible.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29645 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
bd7daa5ac5
commit
767fe5170d
3 changed files with 41 additions and 14 deletions
|
@ -1,3 +1,7 @@
|
|||
Sat Oct 30 17:23:19 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* util.c (ruby_strtod): get rid of overflow/underflow as possible.
|
||||
|
||||
Sat Oct 30 14:37:39 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* configure.in (ruby_pc): erase runtime-defined variables and
|
||||
|
|
|
@ -102,7 +102,14 @@ class TestFloat < Test::Unit::TestCase
|
|||
assert_equal(0.0009765625, Float("0x1p-10"))
|
||||
assert_equal(2.6881171418161356e+43, Float("0x1.3494a9b171bf5p+144"))
|
||||
assert_equal(-3.720075976020836e-44, Float("-0x1.a8c1f14e2af5dp-145"))
|
||||
|
||||
assert_equal(31.0*2**1019, Float("0x0."+("0"*268)+"1fp2099"))
|
||||
assert_equal(31.0*2**1019, Float("0x0."+("0"*600)+"1fp3427"))
|
||||
assert_equal(-31.0*2**1019, Float("-0x0."+("0"*268)+"1fp2099"))
|
||||
assert_equal(-31.0*2**1019, Float("-0x0."+("0"*600)+"1fp3427"))
|
||||
assert_equal(31.0*2**-1027, Float("0x1f"+("0"*268)+".0p-2099"))
|
||||
assert_equal(31.0*2**-1027, Float("0x1f"+("0"*600)+".0p-3427"))
|
||||
assert_equal(-31.0*2**-1027, Float("-0x1f"+("0"*268)+".0p-2099"))
|
||||
assert_equal(-31.0*2**-1027, Float("-0x1f"+("0"*600)+".0p-3427"))
|
||||
end
|
||||
|
||||
def test_divmod
|
||||
|
|
42
util.c
42
util.c
|
@ -2122,21 +2122,38 @@ break2:
|
|||
static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
|
||||
s0 = ++s;
|
||||
adj = 0;
|
||||
aadj = -1;
|
||||
aadj = 1.0;
|
||||
nd0 = -4;
|
||||
|
||||
if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0;
|
||||
do {
|
||||
adj *= 16;
|
||||
adj += (s1 - hexdigit) & 15;
|
||||
} while (*++s && (s1 = strchr(hexdigit, *s)));
|
||||
while (*s == '0') s++;
|
||||
if ((s1 = strchr(hexdigit, *s)) != NULL) {
|
||||
do {
|
||||
adj += aadj * ((s1 - hexdigit) & 15);
|
||||
nd0 += 4;
|
||||
aadj /= 16;
|
||||
} while (*++s && (s1 = strchr(hexdigit, *s)));
|
||||
}
|
||||
|
||||
if (*s == '.') {
|
||||
aadj = 1.;
|
||||
dsign = 1;
|
||||
if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0;
|
||||
do {
|
||||
aadj /= 16;
|
||||
if (nd0 < 0) {
|
||||
while (*s == '0') {
|
||||
s++;
|
||||
nd0 -= 4;
|
||||
}
|
||||
}
|
||||
for (; *s && (s1 = strchr(hexdigit, *s)); ++s) {
|
||||
adj += aadj * ((s1 - hexdigit) & 15);
|
||||
} while (*++s && (s1 = strchr(hexdigit, *s)));
|
||||
if ((aadj /= 16) == 0.0) {
|
||||
while (strchr(hexdigit, *++s));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
dsign = 0;
|
||||
}
|
||||
|
||||
if (*s == 'P' || *s == 'p') {
|
||||
|
@ -2153,17 +2170,16 @@ break2:
|
|||
nd -= '0';
|
||||
c = *++s;
|
||||
/* Float("0x0."+("0"*267)+"1fp2095") */
|
||||
if (abs(nd) > 2095) {
|
||||
if (nd + dsign * nd0 > 2095) {
|
||||
while ('0' <= c && c <= '9') c = *++s;
|
||||
break;
|
||||
}
|
||||
} while ('0' <= c && c <= '9');
|
||||
dval(rv) = ldexp(adj, nd * dsign);
|
||||
}
|
||||
else {
|
||||
if (aadj != -1) goto ret0;
|
||||
dval(rv) = adj;
|
||||
if (dsign) goto ret0;
|
||||
}
|
||||
dval(rv) = ldexp(adj, nd * dsign + nd0);
|
||||
goto ret;
|
||||
}
|
||||
nz0 = 1;
|
||||
|
|
Loading…
Reference in a new issue