From d370cb62d26f212e431d4a7b38db56254c95cd5d Mon Sep 17 00:00:00 2001 From: "NARUSE, Yui" Date: Tue, 2 Feb 2021 15:47:10 +0900 Subject: merge revision(s) 9efd590a13d1e8b8a141c46eabb48c2a1c286d2b,a55eb9a2af7950d180d9d31ffde2bce66710f44f: [Backport #17572] Rationalize floats in coerce [Bug #17572] --- rational.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) Make reciprocal properly of non-integral rational [Bug #17572] --- rational.c | 2 +- test/ruby/test_rational.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) --- rational.c | 18 ++++++++++++------ test/ruby/test_rational.rb | 7 +++++++ version.h | 2 +- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/rational.c b/rational.c index ae134da79f..872bcd7e14 100644 --- a/rational.c +++ b/rational.c @@ -53,6 +53,7 @@ static ID id_abs, id_integer_p, #define f_to_s rb_obj_as_string static VALUE nurat_to_f(VALUE self); +static VALUE float_to_r(VALUE self); inline static VALUE f_add(VALUE x, VALUE y) @@ -1174,11 +1175,17 @@ nurat_coerce(VALUE self, VALUE other) return rb_assoc_new(other, self); } else if (RB_TYPE_P(other, T_COMPLEX)) { - if (k_exact_zero_p(RCOMPLEX(other)->imag)) - return rb_assoc_new(f_rational_new_bang1 - (CLASS_OF(self), RCOMPLEX(other)->real), self); - else + if (!k_exact_zero_p(RCOMPLEX(other)->imag)) return rb_assoc_new(other, rb_Complex(self, INT2FIX(0))); + other = RCOMPLEX(other)->real; + if (RB_FLOAT_TYPE_P(other)) { + other = float_to_r(other); + RBASIC_SET_CLASS(other, CLASS_OF(self)); + } + else { + other = f_rational_new_bang1(CLASS_OF(self), other); + } + return rb_assoc_new(other, self); } rb_raise(rb_eTypeError, "%s can't be coerced into %s", @@ -1870,7 +1877,7 @@ VALUE rb_rational_reciprocal(VALUE x) { get_dat1(x); - return f_rational_new_no_reduce2(CLASS_OF(x), dat->den, dat->num); + return nurat_convert(CLASS_OF(x), dat->den, dat->num, FALSE); } /* @@ -2062,7 +2069,6 @@ integer_denominator(VALUE self) return INT2FIX(1); } -static VALUE float_to_r(VALUE self); /* * call-seq: * flo.numerator -> integer diff --git a/test/ruby/test_rational.rb b/test/ruby/test_rational.rb index 820dd30a82..fe9de64c4c 100644 --- a/test/ruby/test_rational.rb +++ b/test/ruby/test_rational.rb @@ -613,6 +613,13 @@ class Rational_Test < Test::Unit::TestCase assert_nothing_raised(TypeError, '[Bug #5020] [ruby-dev:44088]') do Rational(1,2).coerce(Complex(1,1)) end + + assert_raise(ZeroDivisionError) do + 1 / 0r.coerce(0+0i)[0] + end + assert_raise(ZeroDivisionError) do + 1 / 0r.coerce(0.0+0i)[0] + end end class ObjectX diff --git a/version.h b/version.h index db8fd0f677..bd7503e18e 100644 --- a/version.h +++ b/version.h @@ -12,7 +12,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 0 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 26 +#define RUBY_PATCHLEVEL 27 #define RUBY_RELEASE_YEAR 2021 #define RUBY_RELEASE_MONTH 2 -- cgit v1.2.3