Python ist stärker typisiert als andere Skriptsprachen. Zum Beispiel in Perl:Python: Gibt es eine Möglichkeit, eine automatische Konvertierung von int zu long int zu verhindern?
perl -E '$c=5; $d="6"; say $c+$d' #prints 11
Aber in Python:
>>> c="6"
>>> d=5
>>> print c+d
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
Perl wird eine Zeichenfolge und konvertiert in eine Zahl, und die + -/* **
Betreiber Arbeit überprüfen, wie Sie mit einer Reihe erwarten. PHP ist ähnlich.
Python verwendet +
Strings verketten, so dass die die versuchte Operation von c+d
schlägt fehl, weil c ist eine Zeichenfolge, d ein int. Python hat einen stärkeren Sinn für numeric types als Perl. OK - damit kann ich umgehen.
Aber bedenken Sie:
>>> from sys import maxint
>>> type(maxint)
<type 'int'>
>>> print maxint
9223372036854775807
>>> type(maxint+2)
<type 'long'>
>>> print maxint+2
9223372036854775809
>>> type((maxint+2)+maxint)
<type 'long'>
>>> print ((maxint+2)+maxint)
18446744073709551616
Jetzt Python wird autopromote von einem int, die in diesem Fall ist ein 64-Bit lang (O X, Python 2.6.1) zu einem Python long int, die von beliebiger Genauigkeit ist . Auch wenn die Typen nicht gleich sind, sind sie ähnlich und Python erlaubt die Verwendung der üblichen numerischen Operatoren. Normalerweise ist das hilfreich. Es ist hilfreich, zum Beispiel die Unterschiede zwischen 32 Bit und 64 Bit zu glätten.
Die Umwandlung von int
zu long
ist ein Weg:
>>> type((maxint+2)-2)
<type 'long'>
Sobald die Konvertierung vorgenommen wird, alle Operationen an diesen Variablen werden nun in beliebiger Genauigkeit erfolgen. Die Operationen mit beliebiger Genauigkeit sind um Größenordnungen langsamer als die nativen Int-Operationen. In einem Skript, an dem ich gerade arbeite, würde ich eine gewisse Ausführung haben, die bissig ist und andere, die sich dadurch in Stunden ausdehnen. Bedenken Sie:
>>> print maxint**maxint # execution so long it is essentially a crash
Also meine Frage: Gibt es eine Möglichkeit erlauben zu besiegen oder die Auto-Förderung eines Python int
zu einem Python long
?
bearbeiten, Follow-up: ‚warum auf der Erde würden Sie wollen, C-Stil Überlaufverhalten haben‘
ich einige Kommentare in Form erhalten Das Problem war, dass dieser bestimmte Codecode auf 32 Bits in C und Perl (mit use int
) mit dem Überlaufverhalten von C einwandfrei funktionierte. Es gab einen fehlgeschlagenen Versuch, diesen Code nach Python zu portieren. Pythons unterschiedliches Überlaufverhalten erweist sich als (Teil) des Problems. Der Code hat viele dieser verschiedenen Idiome (C, Perl, etwas Python) gemischt (und diese Kommentare gemischt), also war es eine Herausforderung.
Im Wesentlichen ist die Bildanalyse, die durchgeführt wird, ein scheibenbasierter Hochpassfilter, um einen ähnlichen Bildvergleich durchzuführen. Ein Teil des Hochpassfilters hat eine ganzzahlige Multiplikation von zwei großen Polynomen. Der Überlauf war im Wesentlichen eine "nicht - Vorsicht, es ist groß ..." Art von Logik, so dass das Ergebnis mit einem C-basierten Überlauf beabsichtigt war. Die Verwendung der Horner-Regel mit O (n) Zeit war daher eine Verschwendung, da die größeren Polynome einfach "groß" wären - eine grobe Gerechtigkeitsform der Sättigungsarithmetik des Karussells.
Die Änderung der Schleifenpolynom-Multiplikation in eine Form der FFT ist wahrscheinlich wesentlich schneller.FFT läuft in der Nähe der linearen Zeit gegen O (n) für Horner-Regelpolynom multiplizieren. Der Wechsel von Disc-basiert zu In-Memory wird dies ebenfalls beschleunigen. Die Bilder sind nicht schrecklich groß, aber der ursprüngliche Code wurde zu einer Zeit geschrieben, als sie als "riesig !!!" Der Code-Besitzer ist nicht bereit, seinen geliebten Code zu zerstören, also werden wir sehen. Die "richtige Antwort" für ihn ist wahrscheinlich nur Perl oder C, wenn er diesen Code möchte.
Danke für die Antworten. Ich wusste nichts über Pythons Dezimalmodul, und das schien am nächsten zu dem zu sein, wonach ich fragte - obwohl es in diesem Fall noch andere Probleme zu lösen gibt!
maxint ** maxint ist eine Zahl mit >> 750 Dezimalstellen, ich hoffe du bist nicht wirklich überrascht, es dauert eine Weile. Auch was soll passieren, wenn eine Nummer nicht in 32 Bit passt? –
Sie sagen, dass grundlegende mathematische Operationen Ihre Anwendung Stunden länger laufen lassen, sonst würde es? Das klingt wie dein Fehler, nicht Pythons – Falmarri
Auch was sollte statt Autopromotion passieren? Segfault? Klingt wie du solltest deine Zahlen unter sys.maxint halten ... – Falmarri