**(p1)
public
Show source
static VALUE
nurat_expt(VALUE self, VALUE other)
{
if (k_numeric_p(other) && k_exact_zero_p(other))
return f_rational_new_bang1(CLASS_OF(self), ONE);
if (k_rational_p(other)) {
get_dat1(other);
if (f_one_p(dat->den))
other = dat->num; /* c14n */
}
switch (TYPE(other)) {
case T_FIXNUM:
{
VALUE num, den;
get_dat1(self);
switch (FIX2INT(f_cmp(other, ZERO))) {
case 1:
num = f_expt(dat->num, other);
den = f_expt(dat->den, other);
break;
case -1:
num = f_expt(dat->den, f_negate(other));
den = f_expt(dat->num, f_negate(other));
break;
default:
num = ONE;
den = ONE;
break;
}
return f_rational_new2(CLASS_OF(self), num, den);
}
case T_BIGNUM:
rb_warn("in a**b, b may be too big");
/* fall through */
case T_FLOAT:
case T_RATIONAL:
return f_expt(f_to_f(self), other);
default:
return rb_num_coerce_bin(self, other, id_expt);
}
}