[C++] Modulo operator

Pagina: 1
Acties:

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 19:43
code:
1
punt1 = (punt1-1) % aantalpunten;


Hoe kan hier een negatief getal uitkomen? punt1 is na een tijdje -1 terwijl dat volgens mij toch redelijk onmogelijk moet zijn aangezien aantalpunten een vaste waarde van 3 heeft. Wat zie ik hier over het hoofd? 8)7 :?

Nog wat meer info:
punt1 == 0
aantalpunten == 3

wat naar mijn eer en geweten -1 % 3 oplevert = 2? Toch?

[ Voor 18% gewijzigd door jsiegmund op 17-02-2005 22:18 ]


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
-1 / 3 = 0
-1 % 3 = -1 (dus)
0 * 3 + -1 = -1

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Op een gegeven moment is punt1 0. Daarna haal je er 1 van af: -1. -1%3 == -1.
Sim-pel :)

All my posts are provided as-is. They come with NO WARRANTY at all.


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 19:43
Huh... okee, ik zou zweren dat -1 mod 3 = 2, maar dan werkt dat ding blijkbaar anders... welke operator heeft wel de functionaliteit die ik nodig heb?

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
%, maar dan met + aantalpunten - 1?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 13-05 06:47
Eigenlijk zijn er twee manieren waarop je de modulo-operator zou kunnen definiëren. De methode die jouw compiler er op nahoudt heeft als voordeel dat (-a)%b gelijk is aan a%(-b) en -(a%b), wat ook precies geldt voor deling. Zo beredeneerd is die aanpak wel logisch en soms is dat ook handig.

Verder kun je het ook zo zien. Normaal gesproken geldt: a = b*(a/b) + a%b (voor elke a en b, mits b niet 0). Dat betekent dat de manier waarop de modulo operator werkt samenhangt met de manier waarop de deel operator werkt. De concrete vraag is of bij deling naar beneden afgerond wordt of naar de nul. in C++ wordt altijd naar de nul afgerond en dat betekent dat de modulo negatief moet worden, want als a=-5 en b=3, dan geldt a/3=-5/3=-1 en moet -5%3 wel gelijk zijn aan -2 (terwijl jij misschien 1 wilde zien). Als je omlaag zou afronden geldt echter a/3=-2 en dan is -5%3 inderdaad gelijk aan 1 (want 3*-2+1=-5).

In C89 is dat trouwens niet gespecificeerd. In C99 en C++ gelukkig wel en dus kun je er rekening mee houden zoals OlafvdSpek al zei: a = (a - 1 + b) % b. Let er wel op dat je dan geen getal kan aftrekken wat groter is dan b, anders moet je wat anders verzinnen.

[ Voor 38% gewijzigd door Soultaker op 17-02-2005 23:03 ]


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
De x modulo y van TS is blijkbaar gedefinieerd als "de rest na deling van x door y" (en zo wordt 'ie ook geimplementeerd, met de DIV instructie).

Je kunt er een paar keer y bij optellen alvorens de modulo uit te voeren, zodat je zeker weet dat je resultaat positief is. Bijv, als je weet dat x nooit kleiner kan zijn dan -100, kan je als expressie "value = (x+100 * y) % y" nemen.

[ Voor 6% gewijzigd door MrBucket op 17-02-2005 23:19 . Reden: Moet ik het wel goed zeggen... ]


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
of je controleert van te voren of x < 0 dan moet je eerst met -1 vermenigvuldigen

code:
1
x = x < 0 ? -x % y : x % y

[ Voor 8% gewijzigd door Woy op 18-02-2005 00:05 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

of je gooit je x eerst even door abs() heen ;)

All my posts are provided as-is. They come with NO WARRANTY at all.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
CyBeR schreef op vrijdag 18 februari 2005 @ 00:11:
of je gooit je x eerst even door abs() heen ;)
Nee, abs(-1)%3 is nog steeds geen 2.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
rwb schreef op vrijdag 18 februari 2005 @ 00:05:
of je controleert van te voren of x < 0 dan moet je eerst met -1 vermenigvuldigen

code:
1
x = x < 0 ? -x % y : x % y
Dat werkt toch niet?
-1 wordt dan 1, 1 % 3 = 1.
Terwijl de TS 2 wilde hebben.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Soultaker schreef op donderdag 17 februari 2005 @ 22:37:
Eigenlijk zijn er twee manieren waarop je de modulo-operator zou kunnen definiëren. De methode die jouw compiler er op nahoudt heeft als voordeel dat (-a)%b gelijk is aan a%(-b) en -(a%b), wat ook precies geldt voor deling. Zo beredeneerd is die aanpak wel logisch en soms is dat ook handig.

Verder kun je het ook zo zien. Normaal gesproken geldt: a = b*(a/b) + a%b (voor elke a en b, mits b niet 0). Dat betekent dat de manier waarop de modulo operator werkt samenhangt met de manier waarop de deel operator werkt. De concrete vraag is of bij deling naar beneden afgerond wordt of naar de nul. in C++ wordt altijd naar de nul afgerond en dat betekent dat de modulo negatief moet worden, want als a=-5 en b=3, dan geldt a/3=-5/3=-1 en moet -5%3 wel gelijk zijn aan -2 (terwijl jij misschien 1 wilde zien). Als je omlaag zou afronden geldt echter a/3=-2 en dan is -5%3 inderdaad gelijk aan 1 (want 3*-2+1=-5).

In C89 is dat trouwens niet gespecificeerd. In C99 en C++ gelukkig wel en dus kun je er rekening mee houden zoals OlafvdSpek al zei: a = (a - 1 + b) % b. Let er wel op dat je dan geen getal kan aftrekken wat groter is dan b, anders moet je wat anders verzinnen.
Natuurlijk is a = b*(a/b) + a%b, maar afronden is in C++ expliciet ongespecificeerd. Letterlijk:
If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
De truc a=a-1 -> a = (a - 1 + b) % b is ook uit te breiden naar a-N, zelfs als N>b:
a = (a - (N%b) + b) % b

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
OlafvdSpek schreef op vrijdag 18 februari 2005 @ 09:39:
[...]

Dat werkt toch niet?
-1 wordt dan 1, 1 % 3 = 1.
Terwijl de TS 2 wilde hebben.
Ja je hebt gelijk. Had even niet goed gelezen wat de topic starter nou precies wou.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1