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.
This commit is contained in:
卜部昌平 2020-06-16 10:39:07 +09:00
Родитель 250189f54f
Коммит 03354feb6a
1 изменённых файлов: 26 добавлений и 31 удалений

Просмотреть файл

@ -4008,6 +4008,25 @@ rb_int_positive_pow(long x, unsigned long y)
return int_pow(x, y);
}
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)
{
@ -4017,18 +4036,8 @@ fix_pow(VALUE x, VALUE y)
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)
}
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)
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);