I rearranged the existing code for negative exact large integers y a little; explanation follows. Of course I'm happy to undo this if you prefer.
This code interacts with the new branch in a slightly complicated way: if y is an exact small integer (or half integer), we want to keep using the existing code that calls arb_pow_fmpz_binexp, so the new code needs to come after that test. However, if y is an exact big negative integer, then the current code negates x if its midpoint is negative, which would screw up the new code if we inserted it after the block testing for arb_is_exact(y) && !arf_is_special(arb_midref(x)), keeping the latter unchanged. I assume we want to keep testing that condition only once (as in the original code), so instead of immediately negating x and calling _arb_pow_exp, I chose to instead just store the decision that x needs to be negated. Furthermore, in the original code, _arb_pow_exp takes a flag for negating the input, but the calling code has to negate the result if applicable; given that the decision now needs to be stored, I thought it a little cleaner to store both decisions in one variable and do both steps in _arb_pow_exp. That's what the sign_type is about.
The most obvious alternative would be to store the result of the test arb_is_exact(y) && !arf_is_special(arb_midref(x)) and mirror the original code a bit more closely, inserting the new code truly in between the two parts of the big if block. I'd be entirely happy to do it that way instead if you prefer.
I rearranged the existing code for negative exact large integers y a little; explanation follows. Of course I'm happy to undo this if you prefer.
This code interacts with the new branch in a slightly complicated way: if
y
is an exact small integer (or half integer), we want to keep using the existing code that callsarb_pow_fmpz_binexp
, so the new code needs to come after that test. However, ify
is an exact big negative integer, then the current code negatesx
if its midpoint is negative, which would screw up the new code if we inserted it after the block testing forarb_is_exact(y) && !arf_is_special(arb_midref(x))
, keeping the latter unchanged. I assume we want to keep testing that condition only once (as in the original code), so instead of immediately negatingx
and calling_arb_pow_exp
, I chose to instead just store the decision thatx
needs to be negated. Furthermore, in the original code,_arb_pow_exp
takes a flag for negating the input, but the calling code has to negate the result if applicable; given that the decision now needs to be stored, I thought it a little cleaner to store both decisions in one variable and do both steps in_arb_pow_exp
. That's what thesign_type
is about.The most obvious alternative would be to store the result of the test
arb_is_exact(y) && !arf_is_special(arb_midref(x))
and mirror the original code a bit more closely, inserting the new code truly in between the two parts of the bigif
block. I'd be entirely happy to do it that way instead if you prefer.