2013-10-22 8 views
18

Was soll Integer Division -1/5 zurückgeben? Ich bin total verwirrt von diesem Verhalten. Ich denke, mathematisch sollte es 0 sein, aber Python und Ruby geben -1 zurück.Integer Division durch negative Nummer

Warum verhalten sich verschiedene Sprachen hier anders? Bitte jemand erklären. Vielen Dank.

| Language | Code   | Result | 
|-----------+----------------+--------| 
| ruby  | -1/5   |  -1 | 
| python | -1/5   |  -1 | 
| c   | -1/5   |  0 | 
| clojure | (int (/ -1 5)) |  0 | 
| emacslisp | (/ -1 5)  |  0 | 
| bash  | expr -1/5 |  0 | 
+0

was ist die Frage? Weißt du es nicht? Wenn Sie es für eine der Sprachen wissen wollen, probieren Sie es einfach aus? – usethedeathstar

+0

Sorry, ich meinte -1 nicht 1. Ich kenne die Antwort nicht und ich fühle mich total verwirrt. – ivs

+9

Es gibt keine Antwort. „Integer Division“ ist nicht ein gut definiertes Konzept und jede Spezifikation der Sprache kann für den Betrieb Boden oder Verkürzung auf 0 als definiertes Ergebnis wählen. – geoffspear

Antwort

31

Kurze Antwort: Sprache Designer erhalten zu wählen, wenn ihre Sprache gegen Null, negative Unendlichkeit Runde wird oder positiv unendlich, wenn Integer-Division zu tun. Verschiedene Sprachen haben unterschiedliche Entscheidungen getroffen.

Lange Antwort: Die Sprachautoren von Python und Ruby entschieden beide, dass das Runden auf negative Unendlichkeit mehr Sinn macht als das Runden auf Null (wie C). Der Ersteller von Python schrieb einen Blog-Post über seine Argumentation here. Ich habe viel davon unten ausgeschnitten.

ich gefragt wurde (wieder) heute zu erklären, warum Integer-Division in Python den Boden des Ergebnisses zurück statt

Für positive Zahlen auf Null wie C. Kürzen, gibt es keine Überraschung:

>>> 5//2 
2 

Aber wenn einer der Operanden negativ ist, wird das Ergebnis platt, dh gerundet weg von Null (in Richtung negativ unendlich):

>>> -5//2 
-3 
>>> 5//-2 
-3 

Das stört einige Leute, aber es gibt einen guten mathematischen Grund. Die ganzzahligen Teilungsoperation (//) und seine Geschwister, die Modulo Betrieb (%), gehen zusammen und erfüllen eine schöne mathematische Beziehung (alle Variablen sind ganze Zahlen):

a/b = q with remainder r 

so dass

b*q + r = a and 0 <= r < b 
(assuming a and b are >= 0). 

wenn Sie die Beziehung für die negative ein (wobei b positiv) erweitern möchten, haben Sie zwei Möglichkeiten: wenn Sie q gegen Null gestutzt, r wird negativ werden, so dass die unveränderliche Änderungen 0 < = abs (r) < Andernfalls können Sie q gegen negative Unendlichkeit floor und die Invariante bleibt 0 < = r < b. [update: fixed this para]

In der mathematischen Zahlentheorie bevorzugen Mathematiker immer die letzte Wahl (siehe z.B. Wikipedia). Für Python habe ich die selbe Wahl getroffen, weil es einige interessante Anwendungen der modulo Operation gibt, wo das Zeichen von a uninteressant ist. Erwägen Sie, einen POSIX-Zeitstempel (Sekunden seit Anfang 1970) zu nehmen und ihn in der Tageszeit zu verwandeln. Da es 24 * 3600 = 86400 Sekunden an einem Tag gibt, ist diese Berechnung einfach t% 86400. Aber wenn wir mal vor 1970 mit negativen Zahlen ausdrücken würden, würde die "truncate in Richtung Null" -Regel ein bedeutungsloses Ergebnis geben! Mit der Stockwerksregel funktioniert alles gut.

+0

Danke für die Antwort! – ivs

4

Integer-Division ist die Umsetzung spezifisch. Aus Wikipedias Modulo operation:

Viele Implementierungen verwenden abgeschnitten Teilung wo der Quotient von truncation q = trunc ( a/ n), in anderen Worten definiert ist, ist es die erste Ganzzahl in Richtung von 0 von der exakten rationalen Quotient und der Rest wird durch r = a - n q. Informell gesprochen ist der Quotient "auf Null gerundet" und der Rest hat daher das gleiche Vorzeichen wie der Dividenden.

Knuth beschrieben Teilung platt wobei der Quotient durch die floor function q = floor ( a/ n) und dem Rest r

r = a - nq = a - n \left\lfloor {a \over n} \right\rfloor.

ist

der Quotient wird hier definiert ist immer abgerundet (auch wenn es bereits negativ ist) und der Rest hat das gleiche Vorzeichen wie der Divisor.