ChiQuadat Test -> Bufferoverflow durch 141,4 ** 400

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,

und schon wieder muss ich euch um Hilfe bitten.
Versuche gerade einen ChiQuadrat Test zu implementieren.
Problem ist, dazu muss ich die Summe von so was hier bilden.

Code: Alles auswählen

    
a = y[i] * math.exp(tau_literatur) * math.factorial(x[i]) / tau_literatur**x[i]
Problem ist nun, das tau 141,4 ist und x im Bereich von 400 bis 500.

Habe zwar etwas nachgelesen und gesehen das man mit bignum im Prinzip unendlich große Integer darstellen kann. Dann würde ich zwar vlt. Probleme beim Runden bekomme aber das ist mir hier erst mal egal. Probiere ich es so bekomme ich aber nur die Summe aus inf und 0.
Geht also leider nicht. Oder ich mache es falsch ^^
Probiere ich es anders lande ich dabei das der Bruch zwar aus zwei longs besteht, das Ergebnis aber wieder als Float dargestellt werden will was nicht geht da zu groß.

Was mach ich in python mit so großen Zahlen?
Gibts da keinen Trick mit scipy oder numpy? Habe da bisher noch keine Lösung gefunden.
MfG



p90
BlackJack

@p90: Du bekommst ziemlich wahrscheinlich keinen "Bufferoverflow". Du sprichst von einer Summe, es ist aber nirgends eine Addition in zu sehen. Was ist `bignum`? Python's `int` kann beliebig gross werden -- halt im Rahmen was der Speicher aufnehmen kann.

Der Trick dürfte sein, die Zahlen gar nicht erst so gross werden zu lassen. Ob und wie das geht, kann man ohne mehr Informationen nicht sagen.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Code: Alles auswählen

>>> from decimal import Decimal
>>> from math import factorial
>>> tau = Decimal("141.4")
>>> x = 500
>>> a = x * tau.exp() * factorial(x) / tau**x
>>> print a
9.330685474242022998723698522E+122
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Also erstmal, doch da tritt ein Bufferoverflow auf.
Bei der Division (zumindest denke ich das) versucht er das Ergebnis als Float darzustellen was nicht geht.
Bild
Zum Thema Bignum.
Also wenn ich die PEPs richtig lese gibt es in python vor 3.0 (nebenbei, ich hab hier Python 2.6, vlt ist das das Problem?) intern noch zwei Repräsentationen für Integer, einmal int das beschränkt war, dafür schneller und long was über bignum repräsentiert wird und unlimitiert ist.
Um converting Probleme zu lösen wurde dann bei Python 3.0 int abgeschafft und komplett gegen long bzw. bignum ersetzt.

@numerix
Super!
Nachdem ich tau zu einem Decimal mache und tau.exp() verwende geht es ohne Probleme!
Danke!
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

p90 hat geschrieben:Also erstmal, doch da tritt ein Bufferoverflow auf.
Nein, wie es in der Fehlermeldung auch steht, ist das kein Pufferüberlauf. Dass „Buffer“ hast du dir dazugedacht.
Bei der Division (zumindest denke ich das) versucht er das Ergebnis als Float darzustellen was nicht geht.
Zwar schon bei der Multiplikation, sonst korrekt.
Also wenn ich die PEPs richtig lese gibt es in python vor 3.0 (nebenbei, ich hab hier Python 2.6, vlt ist das das Problem?) intern noch zwei Repräsentationen für Integer, einmal int das beschränkt war, dafür schneller und long was über bignum repräsentiert wird und unlimitiert ist.
Um converting Probleme zu lösen wurde dann bei Python 3.0 int abgeschafft und komplett gegen long bzw. bignum ersetzt.
Nein das hat damit nichts zu tun. Auch wenn long ints und ints in Python3 zusammengeführt wurden, ändert dass nichts daran, dass manche Integer dann immer noch zu groß sind, um durch ein float dargestellt zu werden.
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

@Darii
Oh, stimmt. :oops:
Da steht wirklich kein Buffer....

Woran siehst du das es bereits bei der Multiplikation passiert?
Dachte bisher das es nur bei einer long long Division ein float zurück gegeben wird, eine long, long Multiplikation aber einen long zurück gibt, was ja gehen sollte.

Und als letztes, natürlich gibt es longs die zu Groß sind um als Floats repräsentiert zu werden.
Deshalb hatte ich ja versucht das ganze als longs zu dividieren, selbst wenn ich dann nach hinten was verliere.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

p90 hat geschrieben:Woran siehst du das es bereits bei der Multiplikation passiert?
Dachte bisher das es nur bei einer long long Division ein float zurück gegeben wird, eine long, long Multiplikation aber einen long zurück gibt, was ja gehen sollte.
Weil math.exp einen float zurück gibt und der Ausdruck von links nach rechts abgearbeitet wird.
Deshalb hatte ich ja versucht das ganze als longs zu dividieren, selbst wenn ich dann nach hinten was verliere.
Dann nimm Klammern. Und benutzte besser //, dann sieht man was du willst und das funktioniert später auch mit Python3
Antworten