ruby-changes:62002
From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Mon, 29 Jun 2020 11:07:05 +0900 (JST)
Subject: [ruby-changes:62002] 03354feb6a (master): fix_pow: do not goto into a branch
https://git.ruby-lang.org/ruby.git/commit/?id=03354feb6a From 03354feb6a01b048039cc586dd7135ee71446821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= <shyouhei@r...> Date: Tue, 16 Jun 2020 10:39:07 +0900 Subject: fix_pow: do not goto into a branch I'm not necessarily against every goto in general, but jumping into a branch is definitely a bad idea. Better refactor. diff --git a/numeric.c b/numeric.c index 52d7a74..f0c45fa 100644 --- a/numeric.c +++ b/numeric.c @@ -4009,6 +4009,25 @@ rb_int_positive_pow(long x, unsigned long y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L4009 } static VALUE +fix_pow_inverted(VALUE x, VALUE minusb) +{ + if (x == INT2FIX(0)) { + rb_num_zerodiv(); + } + else { + VALUE y = rb_int_pow(x, minusb); + + if (RB_FLOAT_TYPE_P(y)) { + double d = pow((double)FIX2LONG(x), RFLOAT_VALUE(y)); + return DBL2NUM(1.0 / d); + } + else { + return rb_rational_raw(INT2FIX(1), y); + } + } +} + +static VALUE fix_pow(VALUE x, VALUE y) { long a = FIX2LONG(x); @@ -4017,18 +4036,8 @@ fix_pow(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L4036 long b = FIX2LONG(y); if (a == 1) return INT2FIX(1); - if (a == -1) { - if (b % 2 == 0) - return INT2FIX(1); - else - return INT2FIX(-1); - } - if (b < 0) { - if (a == 0) rb_num_zerodiv(); - y = rb_int_pow(x, LONG2NUM(-b)); - goto inverted; - } - + if (a == -1) return INT2FIX(b % 2 ? -1 : 1); + if (b < 0) return fix_pow_inverted(x, fix_uminus(y)); if (b == 0) return INT2FIX(1); if (b == 1) return x; if (a == 0) return INT2FIX(0); @@ -4036,20 +4045,8 @@ fix_pow(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L4045 } else if (RB_TYPE_P(y, T_BIGNUM)) { if (a == 1) return INT2FIX(1); - if (a == -1) { - if (int_even_p(y)) return INT2FIX(1); - else return INT2FIX(-1); - } - if (BIGNUM_NEGATIVE_P(y)) { - if (a == 0) rb_num_zerodiv(); - y = rb_int_pow(x, rb_big_uminus(y)); - inverted: - if (RB_FLOAT_TYPE_P(y)) { - double d = pow((double)a, RFLOAT_VALUE(y)); - return DBL2NUM(1.0 / d); - } - return rb_rational_raw(INT2FIX(1), y); - } + if (a == -1) return INT2FIX(int_even_p(y) ? 1 : -1); + if (BIGNUM_NEGATIVE_P(y)) return fix_pow_inverted(x, rb_big_uminus(y)); if (a == 0) return INT2FIX(0); x = rb_int2big(FIX2LONG(x)); return rb_big_pow(x, y); @@ -4061,11 +4058,9 @@ fix_pow(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L4058 return DBL2NUM(dy < 0 ? HUGE_VAL : 0.0); } if (a == 1) return DBL2NUM(1.0); - { - if (a < 0 && dy != round(dy)) - return rb_dbl_complex_new_polar_pi(pow(-(double)a, dy), dy); - return DBL2NUM(pow((double)a, dy)); - } + if (a < 0 && dy != round(dy)) + return rb_dbl_complex_new_polar_pi(pow(-(double)a, dy), dy); + return DBL2NUM(pow((double)a, dy)); } else { return rb_num_coerce_bin(x, y, idPow); -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/