Fractions with decimal precision
arbitrary-precision, decimal, long-integer, python
Solution
"Raise to a power" is not a closed operation over the rationals (differently from the usual four arithmetic operations): there is no rational number `r` such that `r == 2 ** 0.5`. Legend has it that Pythagoras (from whose theorem this fact so simply follows) had his disciple Hippasus killed for the horrible crime of proving this; looks like you sympathize wit Pythagoras' alleged reaction;-), given your weird use of "should".
Python's fractions are meant to be exact, so inevitably there are case in which raising a fraction to another fraction's power will be absolutely unable to return a fraction as its result; and "should" just cannot be sensibly applied to a mathematical impossibility.
So the best you can do is to approximate your desired result, e.g. by getting a result that's not an exact fraction (floats are generally considered sufficient for the purpose) and then further approximating it back with a fraction. Most existing pure-Python implementations (there are many `rationals.py` files found around the net;-) prefer not to implement a `**` operator at all, but of course there's nothing stopping you from making a different design decision in your own implementation!-)
Problem
Is there a pure python implementation of `fractions.Fraction` that supports `long`s as numerator and denominator? Unfortunately, exponentiation appears to be coded in to return a float (ack!!!), which should at least support using `decimal.Decimal`. If there isn't, I suppose I can probably make a copy of the library and try to replace occurrences of `float()` with something appropriate from `Decimal` but I'd rather something that's been tested by others before. Here's a code example: ``` base = Fraction.from_decimal(Decimal(1).exp()) a = Fraction(69885L, 53L) x = Fraction(9L, 10L) print base**(-a*x), type(base**(-a*x)) ``` results in `0.0 <type 'float'>` where the answer should be a really small decimal. Update: I've got the following work-around for now (assuming, for a**b, that both are fractions; of course, I'll need another function when exp_ is a float or is itself a Decimal): ``` def fracpow(base, exp_): base = Decimal(base.numerator)/Decimal(base.denominator) exp_ = Decimal(exp_.numerator)/Decimal(exp_.denominator) return base**exp_ ``` which gives the answer 4.08569925773896097019795484811E-516. I'd still be interested if there's a better way of doing this without the extra functions (I'm guessing if I work with the `Fraction` class enough, I'll find other floats working their way into my results).