summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2024-08-23 14:27:16 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2026-05-11 12:24:02 +0900
commit793f4c9572b9d888f0d40fb9d4ec783ea23486e4 (patch)
tree0b6262e4de08a1af4573c755d7b9303214061f0e
parente08ec2b3882efc7f65f9834fa3bd9b63c10988a9 (diff)
[Bug #20697] Parse `r` suffix at Rational
-rw-r--r--rational.c14
-rw-r--r--test/ruby/test_rational.rb5
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