7

是否有fractions.Fraction支持longs 作为分子和分母的纯 python 实现?不幸的是,幂运算似乎被编码为返回一个浮点数(ack!!!),它至少应该支持使用decimal.Decimal.

如果没有,我想我可能可以制作图书馆的副本并尝试float()用适当的东西替换出现的东西,Decimal但我更喜欢以前被其他人测试过的东西。

这是一个代码示例:

base = Fraction.from_decimal(Decimal(1).exp())
a = Fraction(69885L, 53L)
x = Fraction(9L, 10L)

print base**(-a*x), type(base**(-a*x))

导致0.0 <type 'float'>答案应该是一个非常小的小数。

更新:我现在有以下解决方法(假设对于 a**b,两者都是分数;当然,当 exp_ 是浮点数或本身是小数时,我需要另一个函数):

def fracpow(base, exp_):
    base = Decimal(base.numerator)/Decimal(base.denominator)
    exp_ = Decimal(exp_.numerator)/Decimal(exp_.denominator)

    return base**exp_

这给出了答案 4.08569925773896097019795484811E-516。

如果没有额外的功能,如果有更好的方法来做这件事,我仍然会感兴趣(我猜如果我使用这个Fraction类足够多,我会发现其他浮点数进入我的结果)。

4

2 回答 2

7

"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!-)

于 2010-01-11T00:42:29.220 回答
0

您可以为不使用浮点求幂的分数编写自己的“pow”函数。那是你想要做的吗?

这会将分数提高到整数幂,然后回落到浮点数。

def pow( fract, exp ):
    if exp == 0: 
        return fract
    elif exp % 2 == 0:
        t = pow( fract, exp//2 )
        return t*t
    else:
        return fract*pos( fract, exp-1 )
于 2010-01-11T00:09:28.087 回答