Python-Stil integer-division & E-Modul in C
In Python und Ruby, signiert integer-division schneidet in Richtung negativ unendlich, und Ganzzahl-Modul hat die gleichen Zeichen der zweite operand:
>>> (-41) / 3
-14
>>> (-41) % 3
1
Aber in C und Java signed integer-division schneidet in Richtung 0, und Ganzzahl-Modul hat die gleichen Vorzeichen wie der erste operand:
printf("%d\n", (-41) / 3); /* prints "-13" */
printf("%d\n", (-41) % 3); /* prints "-2" */
Was ist der einfachste und effizienteste Weg in C, um die gleiche Art von division und modulo wie in Python und Ruby?
- Das gleiche passiert mit JavaScript: (-41) % 3 === -2
Du musst angemeldet sein, um einen Kommentar abzugeben.
Richtung zur Rundung mit vorzeichenbehafteten integer-division ist, die nicht in älteren C-Normen. Aber in C99 spezifiziert Runden in Richtung null.
Hier der portable code, der funktioniert mit allen Versionen des C-standards und CPU-Architekturen:
Habe ich einige oberflächliche tests und es scheint, die gleichen Ergebnisse wie Python. Dieser code kann nicht maximal effizient, aber ein guter C-compiler kann wahrscheinlich optimieren Sie ausreichend, vor allem, wenn Sie den code im header als static-Funktionen.
Können Sie auch wollen, um einen Blick auf das eng damit verbundene Frage: Integer-division Rundung bei negativen in C++.
Modulo finde ich folgende einfachste. Es ist egal, was die Umsetzung der Konvention ist, dass wir nur zwingen, die Folge der Zeichen, das wir wollen:
Offensichtlich für positive ein. Für negative a Sie benötigen:
Die (vielleicht ein wenig verwirrend) kombiniert, um die folgenden (in C++. In C tun die gleiche Sache mit int und dann mühsam schreiben ein Duplikat für long long):
Können wir ein cheapskate zwei geschätzte "melden" - Funktion, da wir bereits wissen, ein!=0 oder % wäre nicht definiert.
Werden nach dem gleichen Prinzip der Teilung (Blick auf den output statt den input):
Den Multiplikationen wohl könnte teurer sein als nötig, aber kann sein Mikro-optimierte später auf eine pro-Architektur-Grundlage, wenn es sein muss. Zum Beispiel, wenn Sie ein op-Abteilung, die Ihnen Quotienten und den Rest, dann sind Sie sortiert für die division.
[Edit: möglicherweise gibt es einige Grenzfälle, wo dies schief geht, zum Beispiel, wenn der quotient bzw. der Rest ist INT_MAX oder INT_MIN. Aber die Emulation python-Mathematik für große Werte ist eine ganz andere Frage trotzdem ;-)]
[Noch ein edit: ist nicht die standard-python-Implementierung, die in C geschrieben? Sie konnte durchstöbern Sie die Quelle für das, was Sie tun]
Hier ist eine einfache Implementierung von umgehauen, division und modulus in C89:
Hier
div
wird verwendet, weil es hat gut definiert Verhalten.Wenn Sie C++11, hier ist eine vorgefertigte Implementierung von umgehauen, division und modulus:
In C99 und C++11, können Sie verhindern, indem
div
da das Verhalten der division und modulus in C sind nicht mehr abhängig von der Implementierung.Gibt es eine Lösung für diese Frage, das ist viel kürzer (im-code) als der bereits Vorgestellte lieben. Ich werde das format von Ville Laurikari Antwort für mein:
Leider, es scheint, dass die oben genannten Lösungen sind nicht gut. Wenn benchmarking diese Lösung gegen die eine von Ville Laurikari, wird es offensichtlich, dass diese Lösung führt nur halb so schnell.
Die Lektion ist: Während die Verzweigung Anweisungen machen den code langsam, division-Anweisungen sind noch viel schlimmer!
Dachte ich, dass ich trotzdem poste diese Lösung, wenn nur für seine Eleganz.
Die Frage, gefragt, wie emulieren Python-Stil integer-division und modulo. Alle Antworten die hier gegeben werden, übernehmen die Operanden der operation auf ganze zahlen selbst, sondern in Python können auch Schwimmer für seine modulo-operation. So, ich denke, die folgende Antwort löst das problem noch besser:
Sowie für den modulo:
Getestet habe ich die beiden oben genannten Programme vor, wie Python verhält sich mit den folgenden test-code:
Den oben genannten vergleichen das Verhalten von Python-division und modulo mit der C
Implementierungen stellte ich auf 6320 testcases. Da der Vergleich erfolgreich war,
Ich glaube, dass meine Lösung richtig implementiert Python Verhalten von
jeweiligen Operationen.
Er vertieft sich in die hässliche Welt der Schwimmer, aber diese geben korrekte Antworten in Java:
Mache ich keine Aussagen über Ihre Effizienz.
float
fürdouble
oderlong
fürint
es ergeben sich falsche Ergebnisse für einige Eingaben. Auch, wenn Sie den port für diese Instanz von C oder C++ auf einer Plattform, woint
ist 64 bit breit, es werden ebenfalls produzieren falsche Ergebnisse, die für bestimmte Eingänge.