Modulus drift med negativer verdier - rare ting?

stemmer
15

Kan du fortelle meg hvor mye er (-2) % 5? Ifølge min Python er tre, men har du en klok forklaring på dette?

Jeg har lest at i noen språk resultatet kan maskinavhengig, men jeg er ikke sikker på om.

Publisert på 04/09/2008 klokken 13:36
kilden bruker
På andre språk...                            


12 svar

stemmer
16

Forresten: de fleste programmeringsspråk vil være uenig med Python og gi resultatet -2. Avhengig tolkningen av modulus dette er riktig. Imidlertid er den mest avtalte matematiske definisjon angir at modulen til en , og b er den (positive strengt) resten R av delingen av et / b . Mer presist, 0 <= r < b per definisjon.

Svarte 04/09/2008 kl. 13:46
kilden bruker

stemmer
12

Resultatet av modulus operasjonen på negativer synes å være programmeringsspråk avhengig og her er en oversikt http://en.wikipedia.org/wiki/Modulo_operation

Svarte 04/09/2008 kl. 13:41
kilden bruker

stemmer
11

Python-tolkeren er riktig. En (dum) måte å beregne en modul er å trekke eller legge til modulen inntil den resulterende verdien er mellom 0 og (modulus - 1).

for eksempel: 13 mod 5 = (13-5) mod 5 = (13-10) mod 5 = 3

eller i tilfelle: -2 mod 5 = (2 + 5) mod 5 = 3

Svarte 04/09/2008 kl. 13:40
kilden bruker

stemmer
6

Som dokumentasjon sier i binære aritmetiske operasjoner , Python forsikrer at:

De heltallsdeling og modulo operatører er forbundet ved hjelp av den følgende identitet: x == (x/y)*y + (x%y). Heltallsdeling og modulo er også forbundet med den innebygde funksjon divmod (): divmod(x, y) == (x/y, x%y).

Og virkelig,

>>> divmod(-2, 5)
(-1, 3).

En annen måte å visualisere jevnheten av denne metode er å beregne divmodfor en liten sekvens av tall:

>>> for number in xrange(-10, 10):
...     print divmod(number, 5)
...
(-2, 0)
(-2, 1)
(-2, 2)
(-2, 3)
(-2, 4)
(-1, 0)
(-1, 1)
(-1, 2)
(-1, 3)
(-1, 4)
(0, 0)
(0, 1)
(0, 2)
(0, 3)
(0, 4)
(1, 0)
(1, 1)
(1, 2)
(1, 3)
(1, 4)
Svarte 11/07/2010 kl. 22:18
kilden bruker

stemmer
4

Som forklart i andre svar, det er mange valg for en modul operasjon med negative verdier. Generelt ulike språk (og forskjellige maskinarkitekturer) vil gi et annet resultat.

Ifølge Python referansehåndboken ,

Modulo operatøren alltid gir et resultat med det samme fortegn som sin andre operand (eller null); den absolutte verdi av resultatet er strengt mindre enn den absolutte verdien av den andre operand.

Valget er tatt av Python. I utgangspunktet modulo er definert slik at dette alltid holder:

x == (x/y)*y + (x%y)

slik at det er fornuftig at (-2)% 5 = -2 - (-2/5) * 5 = 3

Svarte 04/09/2008 kl. 14:25
kilden bruker

stemmer
4

Vel, bør 0% 5 være 0, ikke sant?

-1% 5 skal være 4 fordi det er den neste tillatt sifret går i motsatt retning (dvs, det kan ikke være 5, siden det er utenfor rekkevidde).

Og følgende sammen med den logikken, -2 må være tre.

Den enkleste måten å tenke på hvordan det vil fungere er at du fortsetter å legge til eller trekke fem til nummeret faller mellom 0 (inkludert) og 5 (eksklusive).

Jeg er ikke sikker på om maskinen avhengighet - Jeg har aldri sett en implementering som var, men jeg kan ikke si det har aldri gjort.

Svarte 04/09/2008 kl. 13:41
kilden bruker

stemmer
0

Det synes å være en felles forvirring mellom begrepene "modulo" og "resten".

I matematikk, bør en rest alltid defineres i samsvar med kvotienten, slik at hvis a / b == c rem dda (c * b) + d == a. Avhengig av hvordan du runde kvotient, får du forskjellige rester.

Men modulo bør alltid gi et resultat 0 <= r < divisor, som bare er forenlig med rund-til-minus-uendelig divisjon hvis du tillater negative heltall. Hvis delingen runder mot null (som er vanlig), modulo og øvrige er bare ekvivalente til ikke-negative verdier.

Noen språk (spesielt C og C ++) ikke definerer de nødvendige avrundings / resten atferd og %er tvetydig. Mange definerer avrunding som mot null, men likevel bruker begrepet modulo hvor resten ville være mer korrekt. Python er relativt uvanlig ved at det runder til negativ uendelig, så modulo og resten er ekvivalente.

Ada runder mot null IIRC, men har både modog remoperatører.

C politikken er ment å tillate kompilatorer å velge den mest effektive gjennomføringen for maskinen, men IMO er en falsk optimalisering, minst i disse dager. En god kompilatoren vil trolig være i stand til å bruke likeverdighet for optimalisering hvor et negativt tall ikke kan skje (og nesten helt sikkert hvis du bruker usignerte typer). På den annen side, hvor negative tall kan skje, du nesten helt sikkert bryr seg om detaljene - for portabilitet grunner til at du må bruke svært nøye utformet overcomplex algoritmer og / eller kontroller for å sikre at du får de resultatene du ønsker uavhengig av avrunding og resten oppførsel.

Med andre ord, gevinsten for denne "optimalisering" er for det meste (om ikke alltid) en illusjon, mens det er svært reelle kostnadene i noen tilfeller - så det er en falsk optimalisering.

Svarte 05/03/2011 kl. 11:16
kilden bruker

stemmer
0

Vær forsiktig så du ikke stole på denne mod atferd i C / C ++ på alle operativsystemer og arkitekturer. Hvis jeg husker riktig, prøvde jeg å stole på C / C ++ kode som

float x2 = x % n;

å holde x2 i området fra 0 til n-1, men negative tall krøp i når jeg skulle kompilere på en OS, men ting vil fungere fint på en annen OS. Dette er gjort for en ond tid debugging siden det skjedde bare halvparten av tiden!

Svarte 04/09/2008 kl. 14:46
kilden bruker

stemmer
0

En forklaring kan være at negative tall er lagret ved hjelp av to-komplement . Når python tolk prøver å gjøre den modul-handling det konverterer til usignert verdi. Som sådan stedet for å gjøre (-2)% 5 det faktisk beregner 0xFFFF_FFFF_FFFF_FFFD% 5, som er tre.

Svarte 04/09/2008 kl. 14:12
kilden bruker

stemmer
0

Resultatet avhenger av språket. Python returnerer fortegnet av divisoren, hvor for eksempel c # gir fortegnet til utbytte (f.eks. -2% 5 returnerer -2 in c #).

Svarte 04/09/2008 kl. 13:53
kilden bruker

stemmer
0

Det er faktisk 3. I modulær aritmetikk , er en modul bare den gjenværende del av en divisjon, og det gjenværende av -2 delt på 5 er tre.

Svarte 04/09/2008 kl. 13:41
kilden bruker

stemmer
0

Vel, -2 delt på fem ville være 0 med en rest på 3. Jeg tror ikke det bør være svært plattform avhengig, men jeg har sett rarere ting.

Svarte 04/09/2008 kl. 13:41
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more