Arrondi de division entière avec des négatifs en C++
Supposons que a
et b
de type int
, et b
est différente de zéro. Considérez le résultat de l'exécution a/b
dans les cas suivants:
-
a
etb
sont tous deux non négatifs. -
a
etb
sont tous deux négatifs. - Exactement l'un d'eux est négatif.
Dans le Cas 1, le résultat est arrondi à l'entier le plus proche. Mais que dit la norme sur les cas 2 et 3? Un vieux brouillon que j'ai trouvé flottant sur Internet indique qu'il est la mise en œuvre dépend (oui, même le cas 2), mais le Comité penche pour le rendre toujours rond vers zéro."Est-ce que quelqu'un sait ce que dit la (dernière) norme? Veuillez répondre uniquement en fonction de la norme, pas de ce qui a du sens, ou de ce que font les compilateurs particuliers.
4 réponses
Selon la révision de mai 2008,
Vous avez raison:
L'opérateur binaire / donne le quotient, et l'opérateur binaire % donne le reste de la division de la première expression par la seconde. Si le deuxième opérande de / ou % est égal à zéro, le comportement est indéfini; sinon (a/b)*b + a%b est égal à A. Si les deux opérandes ne sont pas négatifs, le reste est non négatif; sinon, le signe du reste est défini par l'implémentation75).
Note 75 dit:
Selon les travaux en cours pour la révision de L'ISO C, l'algorithme préféré pour la division entière suit les règles définies dans la norme ISO Fortran, ISO / IEC 1539: 1991, dans laquelle le quotient est toujours arrondi à zéro.
Les Chances sont que C++ soit en retard sur C à cet égard. En l'état, ce n'est pas défini, mais ils ont un œil sur le changement.
Je travaille dans le même département que Stroustrup et avec un membre du Comité. Les choses prennent Les âges pour obtenir accompli, et son sans fin Politique. Si cela semble stupide, c'est probablement le cas.
Comme une mise à jour des autres réponses:
Le Dernier brouillon de C++11, n3242 qui est pour la plupart des fins pratiques identique à la norme C++11 actuelle, dit ceci au point 5.6 4 (page 118):
Pour les opérandes intégraux, l'opérateur / donne le quotient algébrique avec toute partie fractionnaire écartée; (Voir note 80)
Note 80 États (notez que les notes sont non normatives):
80) ceci est souvent appelé troncature vers zéro.
Le Point 4 passe à l'état:
Si le quotient a/b est représentable dans le type du résultat, (a / b) * B + A % b est égal à a.
Qui peut être montré pour exiger que le signe de a%b
soit le même que le signe de a
(quand pas zéro).
Juste un commentaire. Le projet de travail actuel pour la norme c++ corrige en effet le problème "défini par l'implémentation" et demande une troncature vers zéro. Ici est la page web du comité, et de ici est le projet. La question se trouve à la page 112.
Parfois, nous devons prendre du recul, et regarder juste les mathématiques de celui-ci:
Étant donné int x, int y
Si int i1 = x / y et int i2 = x % y
Alors y * i1 + i2 doit être x
Donc, ce n'est pas tellement sur la norme, mais il n'y a qu'une seule façon que cela peut éventuellement être. Si des normes lui permettent d'être d'une autre manière, alors la norme est fausse, et cela signifie que la langue est brisée.