diff --git a/ChangeLog b/ChangeLog index f761117bc6..a4d67e17c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Wed Jul 14 12:20:05 Hirokazu Yamamoto + + * util.c (ruby_strtod): should not convert string in the form of + "-I.FE-X" which both "I" and "F" are ommitted. [ruby-dev:23883] + + * test/ruby/test_float.rb (test_strtod): add test for bug fix. + Wed Jul 14 01:20:21 Hirokazu Yamamoto * array.c: rdoc patch - unified margin. diff --git a/test/ruby/test_float.rb b/test/ruby/test_float.rb index 92c2062948..741093fa61 100644 --- a/test/ruby/test_float.rb +++ b/test/ruby/test_float.rb @@ -61,12 +61,29 @@ class TestFloat < Test::Unit::TestCase assert(a.abs < Float::EPSILON) a = Float("-0.0") assert(a.abs < Float::EPSILON) - a = Float("0." + "00" * Float::DIG + "1") + a = Float("0.0000000000000000001") assert(a != 0.0) - a = Float("+0." + "00" * Float::DIG + "1") + a = Float("+0.0000000000000000001") assert(a != 0.0) - a = Float("-0." + "00" * Float::DIG + "1") + a = Float("-0.0000000000000000001") assert(a != 0.0) + a = Float(".0") + assert(a.abs < Float::EPSILON) + a = Float("+.0") + assert(a.abs < Float::EPSILON) + a = Float("-.0") + assert(a.abs < Float::EPSILON) + a = Float("0.") + assert(a.abs < Float::EPSILON) + a = Float("+0.") + assert(a.abs < Float::EPSILON) + a = Float("-0.") + assert(a.abs < Float::EPSILON) + assert_raise(ArgumentError){Float(".")} + assert_raise(ArgumentError){Float("+")} + assert_raise(ArgumentError){Float("+.")} + assert_raise(ArgumentError){Float("-")} + assert_raise(ArgumentError){Float("-.")} # add expected behaviour here. end end diff --git a/util.c b/util.c index 783b2c00a8..3fe94074e8 100644 --- a/util.c +++ b/util.c @@ -722,7 +722,8 @@ ruby_strtod(string, endPtr) * fractional part of the mantissa, and X * is the exponent. Either of the signs * may be "+", "-", or omitted. Either I - * or F may be omitted, or both. The decimal + * or F may be omitted, but both cannot be + * ommitted at once. The decimal * point isn't necessary unless F is present. * The "E" may actually be an "e". E and X * may both be omitted (but not just one). @@ -745,7 +746,8 @@ ruby_strtod(string, endPtr) * case, fracExp is incremented one for each * dropped digit. */ int mantSize = 0; /* Number of digits in mantissa. */ - int decPt = FALSE; /* mantissa has decimal point. */ + int hasPoint = FALSE; /* Decimal point exists. */ + int hasDigit = FALSE; /* I or F exists. */ const char *pMant; /* Temporarily holds location of mantissa * in string. */ const char *pExp; /* Temporarily holds location of exponent @@ -778,13 +780,13 @@ ruby_strtod(string, endPtr) for ( ; c = *p; p += 1) { if (!ISDIGIT(c)) { - if (c != '.' || decPt) { + if (c != '.' || hasPoint) { break; } - decPt = TRUE; + hasPoint = TRUE; } else { - if (decPt) { /* already in fractional part */ + if (hasPoint) { /* already in fractional part */ fracExp -= 1; } if (mantSize) { /* already in mantissa */ @@ -794,6 +796,7 @@ ruby_strtod(string, endPtr) mantSize += 1; pMant = p; } + hasDigit = TRUE; } } @@ -812,7 +815,11 @@ ruby_strtod(string, endPtr) fracExp += (mantSize - 18); mantSize = 18; } - { + if (!hasDigit) { + fraction = 0.0; + p = string; + } + else { int frac1, frac2; frac1 = 0; for ( ; mantSize > 9; mantSize -= 1) {