Seite 1 von 1

`divmod()` und negative Zahlen

Verfasst: Mittwoch 2. März 2016, 16:26
von mutetella

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... :)

Re: `divmod()` und negative Zahlen

Verfasst: Mittwoch 2. März 2016, 16:40
von 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?

Re: `divmod()` und negative Zahlen

Verfasst: Mittwoch 2. März 2016, 16:48
von mutetella
@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...

Re: `divmod()` und negative Zahlen

Verfasst: Mittwoch 2. März 2016, 16:57
von BlackJack

Re: `divmod()` und negative Zahlen

Verfasst: Donnerstag 3. März 2016, 00:02
von snafu
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.

Re: `divmod()` und negative Zahlen

Verfasst: Donnerstag 3. März 2016, 05:37
von mutetella
@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``.

Re: `divmod()` und negative Zahlen

Verfasst: Donnerstag 3. März 2016, 06:27
von snafu
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.

Re: `divmod()` und negative Zahlen

Verfasst: Donnerstag 3. März 2016, 08:40
von Sirius3
@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.

Re: `divmod()` und negative Zahlen

Verfasst: Donnerstag 3. März 2016, 09:03
von Dav1d
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;
}

Re: `divmod()` und negative Zahlen

Verfasst: Donnerstag 3. März 2016, 10:10
von snafu
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.