159 votes

Opérateur modulo avec des valeurs négatives

Pourquoi de telles opérations ?

std::cout << (-7 % 3) << std::endl;
std::cout << (7 % -3) << std::endl;

donnent-ils des résultats différents ?

-1
1

190voto

PlasmaHH Points 8426

D'après ISO14882:2011(e) 5.6-4 :

L'opérateur binaire / permet d'obtenir le quotient, et le donne le reste de la division de la première expression par la seconde. Si le second opérande de / ou % est zéro, le comportement est non défini. Pour les opérandes intégraux, l'opérateur / produit le quotient algébrique avec toute partie fractionnaire rejetée ; si le quotient a/b est représentable dans le type du résultat, (a/b)*b + a%b est égal à a.

Le reste est une question de mathématiques de base :

(-7/3) => -2
-2 * 3 => -6
so a%b => -1

(7/-3) => -2
-2 * -3 => 6
so a%b => 1

Il convient de noter que

Si les deux opérandes sont non négatifs, le reste est non négatif. le signe du reste est défini par l'implémentation.

de l'ISO14882:2003(e) n'est plus présent dans l'ISO14882:2011(e)

37voto

Kto To Points 321
a % b

en c++ par défaut :

(-7/3) => -2
-2 * 3 => -6
so a%b => -1

(7/-3) => -2
-2 * -3 => 6
so a%b => 1

en python :

-7 % 3 => 2
7 % -3 => -2

en c++ vers python :

(b + (a%b)) % b

19voto

Nawaz Points 148870

En signe dans de tels cas (c'est-à-dire lorsque l'un des opérandes ou les deux sont négatifs) est défini par l'implémentation. La spécification indique au §5.6/4 (C++03),

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 second opérande de / ou % est zéro, le comportement est indéfini ; sinon (a/b)*b + a%b est égal à a. Si les deux opérandes sont non négatifs, le reste est non négatif ; si ce n'est pas le cas, le signe du reste est défini par l'implémentation .

C'est tout ce que le langage a à dire, en ce qui concerne le C++03.

-1voto

Petri Points 49

J'ai décidé de mettre en œuvre le "modulo négatif" nécessaire dans la gestion de la mémoire tampon circulaire du filtre FIR à phase linéaire de la manière suivante

        // Indeces to delay line (Note! Up/Down modulo K counters!)
        int negitmp = (middle - coefi);
        unsigned int negi = (negitmp < 0) ? (CBufLen_c + negitmp) : (negitmp % CBufLen_c);
        unsigned int posi = (middle + coefi) % CBufLen_c;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X