Pregunta

¿Hay una aplicación Python pura de fractions.Fraction que soporta longs como numerador y el denominador? Por desgracia, la exponenciación parece estar codificado en devolver un flotador (ACK !!!), lo que debería, al menos, el apoyo usando decimal.Decimal.

Si no lo hay, supongo probable que pueda hacer una copia de la biblioteca y tratar de sustituir las ocurrencias de float() con algo apropiado de Decimal pero prefiero algo que ha sido probado por otros antes.

Aquí hay un ejemplo de código:

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

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

resultados en 0.0 <type 'float'> donde la respuesta debe ser una muy pequeña decimal.

Actualizar : Tengo la siguiente solución alternativa por ahora (suponiendo, por un ** b, que ambos son fracciones; por supuesto, voy a necesitar otra función cuando EXP_ es una flotador o es en sí mismo un decimal):

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

    return base**exp_

que da la respuesta 4.08569925773896097019795484811E-516.

todavía estaría interesado si hay una mejor manera de hacer esto sin las funciones adicionales (supongo que si trabajo con la clase Fraction suficiente, voy a encontrar otros flotadores que trabajan su camino en mis resultados).

¿Fue útil?

Solución

"elevar a una potencia" no es una operación cerrada sobre los racionales (a diferencia de los habituales cuatro operaciones aritméticas): no hay un número r racional tal que r == 2 ** 0.5. La leyenda dice que Pitágoras (de cuyo teorema de este hecho por lo que simplemente sigue) tuvo su discípulo Hípaso mató para el horrible crimen de probar esto; Parece que simpatizan ingenio supuesta reacción de Pitágoras ;-), dada su utilización extraña de 'debería'.

fracciones de Python están destinados a ser exacta, por lo que inevitablemente hay caso en el que elevar una fracción del poder de otra fracción será absolutamente no para volver una fracción como su resultado; y "debe" simplemente no se pueden aplicar con sensatez a una imposibilidad matemática.

Así que lo mejor que puede hacer es aproximada el resultado deseado, por ejemplo, por conseguir un resultado que no es una fracción exacta (flotadores se consideran generalmente suficiente para el propósito) y luego se aproxima más de nuevo con una fracción. La mayoría de las implementaciones de Python puro-existentes (no se muchos archivos rationals.py encuentran alrededor de la red ;-) prefieren no aplicar un operador de ** en absoluto, pero por supuesto no hay nada que nos impida tomar una decisión diferente en el diseño su propia implementación -)

Otros consejos

Puede escribir su propia función "prisionero de guerra" para las fracciones que no se utilizan en coma flotante exponenciación. Es eso lo que estás tratando de hacer?

Esto elevará una fracción a una potencia entera con la caída de nuevo a flotar.

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 )
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top