+
+ const numeric res = num_basis->power(*num_exponent);
+ if (res.is_crational()) {
+ return res;
+ }
+ GINAC_ASSERT(!num_exponent->is_integer()); // has been handled by now
+
+ // ^(c1,n/m) -> *(c1^q,c1^(n/m-q)), 0<(n/m-q)<1, q integer
+ if (basis_is_crational && exponent_is_crational
+ && num_exponent->is_real()
+ && !num_exponent->is_integer()) {
+ const numeric n = num_exponent->numer();
+ const numeric m = num_exponent->denom();
+ numeric r;
+ numeric q = iquo(n, m, r);
+ if (r.is_negative()) {
+ r += m;
+ --q;
+ }
+ if (q.is_zero()) { // the exponent was in the allowed range 0<(n/m)<1
+ if (num_basis->is_rational() && !num_basis->is_integer()) {
+ // try it for numerator and denominator separately, in order to
+ // partially simplify things like (5/8)^(1/3) -> 1/2*5^(1/3)
+ const numeric bnum = num_basis->numer();
+ const numeric bden = num_basis->denom();
+ const numeric res_bnum = bnum.power(*num_exponent);
+ const numeric res_bden = bden.power(*num_exponent);
+ if (res_bnum.is_integer())
+ return (new mul(power(bden,-*num_exponent),res_bnum))->setflag(status_flags::dynallocated | status_flags::evaluated);
+ if (res_bden.is_integer())
+ return (new mul(power(bnum,*num_exponent),res_bden.inverse()))->setflag(status_flags::dynallocated | status_flags::evaluated);
+ }
+ return this->hold();
+ } else {
+ // assemble resulting product, but allowing for a re-evaluation,
+ // because otherwise we'll end up with something like
+ // (7/8)^(4/3) -> 7/8*(1/2*7^(1/3))
+ // instead of 7/16*7^(1/3).
+ ex prod = power(*num_basis,r.div(m));
+ return prod*power(*num_basis,q);
+ }