зеркало из https://github.com/github/ruby.git
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:
Родитель
250189f54f
Коммит
03354feb6a
57
numeric.c
57
numeric.c
|
@ -4008,6 +4008,25 @@ rb_int_positive_pow(long x, unsigned long y)
|
||||||
return int_pow(x, 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
|
static VALUE
|
||||||
fix_pow(VALUE x, VALUE y)
|
fix_pow(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
|
@ -4017,18 +4036,8 @@ fix_pow(VALUE x, VALUE y)
|
||||||
long b = FIX2LONG(y);
|
long b = FIX2LONG(y);
|
||||||
|
|
||||||
if (a == 1) return INT2FIX(1);
|
if (a == 1) return INT2FIX(1);
|
||||||
if (a == -1) {
|
if (a == -1) return INT2FIX(b % 2 ? -1 : 1);
|
||||||
if (b % 2 == 0)
|
if (b < 0) return fix_pow_inverted(x, fix_uminus(y));
|
||||||
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 (b == 0) return INT2FIX(1);
|
if (b == 0) return INT2FIX(1);
|
||||||
if (b == 1) return x;
|
if (b == 1) return x;
|
||||||
if (a == 0) return INT2FIX(0);
|
if (a == 0) return INT2FIX(0);
|
||||||
|
@ -4036,20 +4045,8 @@ fix_pow(VALUE x, VALUE y)
|
||||||
}
|
}
|
||||||
else if (RB_TYPE_P(y, T_BIGNUM)) {
|
else if (RB_TYPE_P(y, T_BIGNUM)) {
|
||||||
if (a == 1) return INT2FIX(1);
|
if (a == 1) return INT2FIX(1);
|
||||||
if (a == -1) {
|
if (a == -1) return INT2FIX(int_even_p(y) ? 1 : -1);
|
||||||
if (int_even_p(y)) return INT2FIX(1);
|
if (BIGNUM_NEGATIVE_P(y)) return fix_pow_inverted(x, rb_big_uminus(y));
|
||||||
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 == 0) return INT2FIX(0);
|
if (a == 0) return INT2FIX(0);
|
||||||
x = rb_int2big(FIX2LONG(x));
|
x = rb_int2big(FIX2LONG(x));
|
||||||
return rb_big_pow(x, y);
|
return rb_big_pow(x, y);
|
||||||
|
@ -4061,11 +4058,9 @@ fix_pow(VALUE x, VALUE y)
|
||||||
return DBL2NUM(dy < 0 ? HUGE_VAL : 0.0);
|
return DBL2NUM(dy < 0 ? HUGE_VAL : 0.0);
|
||||||
}
|
}
|
||||||
if (a == 1) return DBL2NUM(1.0);
|
if (a == 1) return DBL2NUM(1.0);
|
||||||
{
|
if (a < 0 && dy != round(dy))
|
||||||
if (a < 0 && dy != round(dy))
|
return rb_dbl_complex_new_polar_pi(pow(-(double)a, dy), dy);
|
||||||
return rb_dbl_complex_new_polar_pi(pow(-(double)a, dy), dy);
|
return DBL2NUM(pow((double)a, dy));
|
||||||
return DBL2NUM(pow((double)a, dy));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return rb_num_coerce_bin(x, y, idPow);
|
return rb_num_coerce_bin(x, y, idPow);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче