代码之家  ›  专栏  ›  技术社区  ›  Noah

小数精度分数

  •  6
  • Noah  · 技术社区  · 16 年前

    fractions.Fraction 支持 long s作为分子和分母?不幸的是,求幂似乎被编码为返回浮点(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_u是浮点或本身是十进制时,我需要另一个函数):

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

    答案是4.0856992577389609701795484811E-516。

    我仍然很感兴趣的是,是否有更好的方法在不使用额外功能的情况下实现这一点(我猜如果我使用 Fraction 类足够多,我会发现其他浮动工作的方式进入我的结果)。

    2 回复  |  直到 16 年前
        1
  •  7
  •   Alex Martelli    16 年前

    “升幂”不是有理数的闭合运算(不同于通常的四次算术运算):没有有理数 r r == 2 ** 0.5 . 传说毕达哥拉斯(毕达哥拉斯的定理就是如此)因为证明这一点的可怕罪行而杀害了他的弟子希帕索斯;看来你同情毕达哥拉斯所谓的反应;-),考虑到你对“应该”的奇怪用法。

    Python的分数应该是精确的,所以不可避免地会出现将一个分数提升到另一个分数的幂的情况 返回一个分数作为其结果;“应该”不能合理地应用于数学上的不可能。

    所以你能做的就是 您所需的结果,例如,通过得到一个不是精确分数的结果(通常认为浮点数足以达到目的),然后用分数进一步逼近它。大多数现有的纯Python实现(有 许多的 rationals.py 在网上找到的文件;-)宁愿不实施 **

        2
  •  0
  •   S.Lott    16 年前

    您可以为不使用浮点求幂的分数编写自己的“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 )
    
    推荐文章