`divmod()` und negative Zahlen

Alles, was nicht direkt mit Python-Problemen zu tun hat. Dies ist auch der perfekte Platz für Jobangebote.
Antworten
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Code: Alles auswählen

>>> divmod(-3, 2)
(-2, 1)
>>> divmod(3, 2)
(1, 1)
>>> divmod(-3, -2)
(1, -1)
Falls es eine Erklärung gibt, die von einer mathematischen Wildsau wie mir verstanden wird, wäre ich dafür sehr dankbar... :)
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Welcher Teil davon macht Dir denn Probleme? ``divmod(a, b)`` ist ja das gleiche wie ``(a // b, a % b)``. Verstehst Du jetzt die ganzzahlige Division nicht? Oder den Modulo-Operator?
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@BlackJack
Stimmt. Hat eigentlich nix mit `divmod()` zu tun... Ich versteh' die Division einer negativen Zahl nicht. Weshalb ergibt

Code: Alles auswählen

>>> -3 / 2
-2
aber

Code: Alles auswählen

>>> -3 / -2
1
Ich hätte auch im ersten Fall `-1` erwartet...
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
snafu
User
Beiträge: 6879
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

mutetella hat geschrieben:Weshalb ergibt

Code: Alles auswählen

>>> -3 / 2
-2
aber

Code: Alles auswählen

>>> -3 / -2
1
Ich hätte auch im ersten Fall `-1` erwartet...
-3 : -2 = 1,5

Das sind stinknormale mathematische Regeln: Teilen oder Multiplizieren von zwei Zahlen mit gleichem Vorzeichen ergibt immer Plus und bei unterschiedlichem Vorzeichen Minus. Davon wird - wie auch bei anderen Integer-Divsionen - bis zur nächsten Ganzzahl abgerundet, d.h. es wird bei diesem Beispiel zu 1 gemacht.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@snafu
Das ist mir soweit schon klar… Was ich allerdings noch nicht verstehe (hab' aber auch BlackJacks Link noch nicht durch…), ist das Ergebnis -2, wenn ich -3 durch 2 teile. Weshalb hier nicht -1. Python 2 rundet hier auf, obwohl es bei gleichen Vorzeichen abrundet. Unter Python 3 erhalte ich erwartungsgemäß ``-3 / 2 = -1.5``.
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
snafu
User
Beiträge: 6879
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

mutetella hat geschrieben:Python 2 rundet hier auf, obwohl es bei gleichen Vorzeichen abrundet. Unter Python 3 erhalte ich erwartungsgemäß ``-3 / 2 = -1.5``.
Da bringst du jetzt zwei Dinge durcheinander: Das Rundungsverhalten bei der ganzzahligen Division (die übrigens nicht nur von Python genutzt wird, sondern ein mathematisches Konzept ist) hat nichts mit dem Vorzeichen der Zahlen zu tun. Es wird wie gesagt immer bis zur nächsten ganzen Zahl abgerundet. Wenn das Ergebnis also -1,5 ist, dann ist die nächstniedrigere ganze Zahl (wegen *Ab*rundung) die -2.

Python 3 verhält sich genau so, wenn du ``-3 // 2`` schreibst, da der `//`-Operator die ganzzahlige Division erzwingt.
Sirius3
User
Beiträge: 18296
Registriert: Sonntag 21. Oktober 2012, 17:20

@snafu: wie der von BlackJack verlinkte Artikel schön beschreibt, gibt es eben verschiedene Arten, wie man eine Ganzzahldivision mathematisch definiert. Hier haben Fortran, C, Java und x86-Prozessoren einen anderen Weg eingeschlagen als z.B. Python:

Code: Alles auswählen

printf("%d %d\n", (-3) / 2, (-3) % 2);
>>> -1 -1

Code: Alles auswählen

print divmod(-3,2)
>>> (-2, 1)
Man muß halt, wie so oft, genau wissen, wie sich welche Programmiersprache verhält und ob dieses Verhalten im Sprachstandard definiert ist, weil man sich sonst nicht drauf verlassen kann.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Sirius3 hat geschrieben:Man muß halt, wie so oft, genau wissen, wie sich welche Programmiersprache verhält und ob dieses Verhalten im Sprachstandard definiert ist, weil man sich sonst nicht drauf verlassen kann.
Was ganz schön verwirrend sein kann, wenn man Sachen in IPython testet und die sich dann anders verhalten (and man nicht weiß, dass sich Division/Modulo anders verhalten) ...

Code: Alles auswählen

int py_div(int a, int b) {
    return a < 0 ? (a - (b-1)) / b : a / b;
}

int py_mod(int a, int b) {
    return cast(uint)a % b;
}
the more they change the more they stay the same
Benutzeravatar
snafu
User
Beiträge: 6879
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Sirius3 hat geschrieben:@snafu: wie der von BlackJack verlinkte Artikel schön beschreibt, gibt es eben verschiedene Arten, wie man eine Ganzzahldivision mathematisch definiert. Hier haben Fortran, C, Java und x86-Prozessoren einen anderen Weg eingeschlagen als z.B. Python
Das war mir neu. Ich dachte, das Vorgehen sei bei den meisten Sprachen gleich. Ich hatte es allerdings nicht überprüft.
Antworten