Question

Y at-il une implémentation pure python de fractions.Fraction qui prend en charge longs comme numérateur et le dénominateur? Malheureusement, exponentiation semble être codé pour retourner un flotteur (ack !!!), ce qui devrait au moins support à l'aide decimal.Decimal.

S'il n'y a pas, je suppose que je peux probablement faire une copie de la bibliothèque et essayer de remplacer les occurrences de float() avec quelque chose d'approprié de Decimal mais je préfère quelque chose qui a été testé par d'autres avant.

Voici un exemple de code:

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

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

résultats dans 0.0 <type 'float'> où la réponse doit être un nombre décimal vraiment petit.

Mise à jour : J'ai l'un ** b, autour de travail pour suivre maintenant (en supposant que les deux sont des fractions, bien sûr, je besoin d'une autre fonction lorsque exp_ est un flotteur ou est lui-même une décimale):

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

    return base**exp_

qui donne la réponse 4.08569925773896097019795484811E-516.

Je serais toujours intéressé s'il y a une meilleure façon de le faire sans que les fonctions supplémentaires (je devine si je travaille avec la classe assez Fraction, je vais trouver d'autres flotteurs leur chemin dans mes résultats).

Était-ce utile?

La solution

« Raise à une puissance » est pas une opération fermée au cours des rationals (différemment des quatre opérations arithmétiques habituelles): il n'y a pas rationnel r tel que r == 2 ** 0.5. La légende veut que Pythagore (dont le théorème de ce fait suite si simplement) avait son disciple Hippasus tué pour le crime horrible de le prouver; Il semble que vous sympathiser wit réaction présumée de Pythagore ;-), compte tenu de votre utilisation bizarre de « devrait ».

Les fractions de Python sont destinés à être exacte, donc forcément il y a des cas où élever une fraction au pouvoir d'une autre fraction sera absolument pas pour revenir une fraction comme résultat; et « devrait » juste ne peut être raisonnablement appliqué à une impossibilité mathématique.

Donc, la meilleure que vous pouvez faire est de approximative résultat souhaité, par exemple en obtenant un résultat qui n'est pas une fraction exacte (flotteurs sont généralement considérés comme suffisants à cet effet), puis se rapprochant de plus en arrière avec une fraction. La plupart des implémentations pure Python existants (il y a nombre fichiers rationals.py trouvés sur le net ;-) préfèrent ne pas mettre en œuvre un opérateur ** du tout, mais bien sûr, il n'y a rien qui vous empêche de prendre une décision de conception différente votre propre implémentation -)

Autres conseils

Vous pouvez écrire votre propre fonction « pow » pour les fractions qui n'utilise pas exponentiation à virgule flottante. Est-ce que vous essayez de faire?

Cela soulèvera une fraction à une puissance entière avec retomber à flotter.

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 )
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top