C en Python – verschillend gedrag van de modulo (%) bewerking

Ik heb ontdekt dat dezelfde mod-bewerking verschillende resultaten oplevert, afhankelijk van de taal die wordt gebruikt.

In Python:

-1 % 10

produceert 9

In C produceert het -1!

  1. Welke is de juiste modulo?
  2. Hoe maak je de mod-bewerking in C hetzelfde als in Python?

Antwoord 1, autoriteit 100%

  1. Beide varianten zijn correct, maar in de wiskunde (met name getaltheorie) is de modulovan Python meest gebruikt.
  2. In C doe je ((n % M) + M) % Mom hetzelfde resultaat te krijgen als in Python. bijv. ((-1 % 10) + 10) % 10. Merk op hoe het nog steeds werkt voor positieve gehele getallen: ((17 % 10) + 10) % 10 == 17 % 10, evenals voor beide varianten van C-implementaties (positieve of negatieve rest).

Antwoord 2, autoriteit 41%

Python heeft een “echte” modulo-bewerking, terwijl C een rest-bewerking heeft.

Het heeft een directe relatie met hoe de negatieve gehele deling wordt afgehandeld, d.w.z. afgerond naar 0 of min oneindig. Python rondt af naar min oneindig en C(99) naar 0, maar in beide talen (n/m)*m + n%m == n, dus de %-operator moet in de juiste richting compenseren.

Ada is explicieter en heeft beide, als moden rem.


Antwoord 3, autoriteit 20%

In C89/90 is het gedrag van de deling-operator en de rest-operator met negatieve operanden door de implementatie gedefinieerd, wat betekent dat je, afhankelijk van de implementatie, beide gedragingen kunt krijgen. Het is alleen vereist dat de operators het met elkaar eens zijn: van a / b = qen a % b = rvolgt a = b * q + r. Gebruik statische beweringen in uw code om het gedrag te controleren, als het kritisch afhankelijk is van het resultaat.

In C99 is het gedrag dat u waarneemt standaard geworden.

In feite hebben beide gedragingen een bepaalde logica. Het gedrag van Python implementeert de echte modulo-bewerking. Het gedrag dat je hebt waargenomen, is dat C consistent is met afronding naar 0 (het is ook Fortran-gedrag).

Een van de redenen waarom afronding naar 0 in C de voorkeur heeft, is dat het vrij natuurlijk is om te verwachten dat het resultaat van -a / bhetzelfde is als -(a / b). In het geval van echt modulo-gedrag, zou -1 % 10resulteren in 9, wat betekent dat -1 / 10-1 moet zijn. Dit kan als nogal onnatuurlijk worden beschouwd, aangezien -(1 / 10)0 is.


Antwoord 4, autoriteit 6%

Beide antwoorden zijn correct aangezien -1 modulo 10hetzelfde is als 9 modulo 10.

r = (a mod m)
a = n*q + r

Je kunt er zeker van zijn dat |r| < |n|, maar niet wat de waarde van ris. Er zijn 2 antwoorden, negatief en positief.


In C89, hoewel het antwoord altijd correct zal zijn, is de exacte waarde van een modulo-bewerking (ze noemen het rest) niet gedefinieerd, wat betekent dat het een negatief resultaat of een positief resultaat kan zijn. In C99 wordt het resultaat gedefinieerd.

Als je echter een positief antwoord wilt, kun je gewoon 10 toevoegen als je antwoord negatief is.

Om de modulo-operator in alle talen hetzelfde te laten werken, onthoud het volgende:

n mod M == (n + M) mod M

en in het algemeen:

n mod M == (n + X * M) mod M

Other episodes