diff options
| author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2024-08-23 14:27:16 +0900 |
|---|---|---|
| committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2026-05-11 12:24:02 +0900 |
| commit | 793f4c9572b9d888f0d40fb9d4ec783ea23486e4 (patch) | |
| tree | 0b6262e4de08a1af4573c755d7b9303214061f0e | |
| parent | e08ec2b3882efc7f65f9834fa3bd9b63c10988a9 (diff) | |
[Bug #20697] Parse `r` suffix at Rational
| -rw-r--r-- | rational.c | 14 | ||||
| -rw-r--r-- | test/ruby/test_rational.rb | 5 |
2 files changed, 18 insertions, 1 deletions
diff --git a/rational.c b/rational.c index 329a06845a..d6214451b4 100644 --- a/rational.c +++ b/rational.c @@ -2304,6 +2304,12 @@ islettere(int c) return (c == 'e' || c == 'E'); } +inline static int +isletterr(int c) +{ + return (c == 'r' || c == 'R'); +} + static VALUE negate_num(VALUE num) { @@ -2353,7 +2359,13 @@ read_num(const char **s, const char *const end, VALUE *num, VALUE *nexp) ok = 1; } - if (ok && *s + 1 < end && islettere(**s)) { + if (!ok || *s >= end) { + /* failed or finish */ + } + else if (isletterr(**s)) { + (*s)++; + } + else if (*s + 1 < end && islettere(**s)) { (*s)++; expsign = read_sign(s, end); exp = rb_int_parse_cstr(*s, end-*s, &e, NULL, diff --git a/test/ruby/test_rational.rb b/test/ruby/test_rational.rb index e75e569106..a02e11acc5 100644 --- a/test/ruby/test_rational.rb +++ b/test/ruby/test_rational.rb @@ -130,6 +130,7 @@ class Rational_Test < Test::Unit::TestCase assert_equal(Rational(111, 10), Rational('1.11e1')) assert_equal(Rational(111, 100), Rational('1.11e0')) assert_equal(Rational(111, 1000), Rational('1.11e-1')) + assert_equal(Rational(5, 4), Rational('3.0r','2.4R')) end def test_conv_error @@ -842,6 +843,10 @@ class Rational_Test < Test::Unit::TestCase ng[5, 3, '5/3x'] ng[5, 1, '5/-3'] + + ok[30, 24, '3.0r/2.4R'] + ng[30, 24, '3.0r/2.4re1'] + ng[30, 240, '3.0r/2.4e1r'] end def test_parse_zero_denominator |
