Frage

Gibt es eine reine Python-Implementierung von fractions.Fraction dass Stützen longs als Zähler und Nenner? Leider scheint Potenzierung kodiert zu werden in einem Schwimmer (ack !!!) zurückzukehren, die zumindest Unterstützung mit decimal.Decimal sollte.

Wenn es nicht den Fall, ich nehme an, ich wahrscheinlich eine Kopie der Bibliothek machen und versuchen, das Auftreten von float() mit etwas angemessen von Decimal zu ersetzen, aber ich würde lieber etwas, das zuvor von anderen getestet worden ist.

Hier ist ein Codebeispiel:

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

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

Ergebnisse in 0.0 <type 'float'> wo die Antwort sollte eine wirklich kleine dezimal sein.

Aktualisieren : Ich habe die bekommt folgende Behelfslösung jetzt (unter der Annahme, für ein ** b, dass beide Fraktionen sind, natürlich, ich werde eine andere Funktion benötigen, wenn EXP_ a schwimmen oder selbst ein Dezimal):

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

    return base**exp_

, die die Antwort 4.08569925773896097019795484811E-516 gibt.

Ich würde noch interessieren, ob es ein besserer Weg, dies zu tun, ohne die zusätzlichen Funktionen (ich nehme an, wenn ich mit der Fraction Klasse genug arbeiten, werde ich anderen Schwimmer ihren Weg in meine Ergebnisse finden).

War es hilfreich?

Lösung

„erhöhen, um eine Leistung“ ist nicht ein geschlossene Betrieb über das rationals (anders als die üblichen vier arithmetischen Operationen): Es gibt keine rationale Zahl r so dass r == 2 ** 0.5. Die Legende besagt, dass Pythagoras (aus dessen Satz diese Tatsache so einfach folgt) hatte seinen Schüler Hippasus für die schrecklichen Verbrechen getötet, dies zu beweisen; Sieht aus wie Sie sympathisieren Witz Pythagoras' angebliche Reaktion ;-), da Ihre seltsame Verwendung ‚sollte‘.

Pythons Fraktionen gemeint sind genau zu sein, so unvermeidlich gibt es Fall, in dem eine Fraktion zu einer anderen Fraktion der Potenzierung wird absolut nicht mehr einen Bruchteil als Ergebnis zurückzukehren; und „sollte“ einfach nicht sinnvoll auf eine mathematische Unmöglichkeit angewendet werden.

So das Beste, was Sie tun können, ist zu ungefähres das gewünschte Ergebnis, z.B. durch ein Ergebnis zu erzielen, die keine exakte Fraktion ist (Schwimmer ist für die Zwecke der Regel ausreichend angesehen wird) und dann weiter annähert, es mit einem Bruchteil zurück. Die meisten existierenden pure-Python-Implementierungen (es gibt viele rationals.py Dateien gefunden das Netz um ;-) lieber keinen ** Operator überhaupt implementieren, aber natürlich gibt es nichts mehr im Wege stehen ein anderes Design Entscheidungsfindung in Ihre eigene Implementierung! -)

Andere Tipps

Sie können Ihre eigenen „pow“ -Funktion für Fraktionen schreiben, die nicht Floating-Point-Potenzierung nicht verwendet. Ist das, was Sie versuchen zu tun?

Dies wird einen Bruchteil einer ganzen Zahl potenziert mit zurück in die Schwimmer fallen.

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 )
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top