Voici une nouvelle réponse à une ancienne question, basée sur cet article de Microsoft Research et ses références.
Notez qu'à partir de C11 et C ++ 11, la sémantique de div
est devenue une troncature vers zéro (voir [expr.mul]/4
). De plus, pour D
divisé par d
, C ++ 11 garantit ce qui suit sur le quotient qT
et le resterT
auto const qT = D / d;
auto const rT = D % d;
assert(D == d * qT + rT);
assert(abs(rT) < abs(d));
assert(signum(rT) == signum(D));
où signum
correspond à -1, 0, +1, selon que son argument est <, ==,> que 0 (voir cette Q&R pour le code source).
Avec une division tronquée, le signe du reste est égal au signe du dividendeD
, c'est-à-dire -1 % 8 == -1
. C ++ 11 fournit également une std::div
fonction qui renvoie une structure avec des membres quot
et rem
selon une division tronquée.
Il y a d'autres définitions possibles, par exemple la division dite par étage peut être définie en termes de division tronquée intégrée
auto const I = signum(rT) == -signum(d) ? 1 : 0;
auto const qF = qT - I;
auto const rF = rT + I * d;
assert(D == d * qF + rF);
assert(abs(rF) < abs(d));
assert(signum(rF) == signum(d));
Avec la division au sol, le signe du reste est égal au signe du diviseurd
. Dans des langues telles que Haskell et Oberon, il existe des opérateurs intégrés pour la division par étage. En C ++, vous devez écrire une fonction en utilisant les définitions ci-dessus.
Encore une autre façon est la division euclidienne , qui peut également être définie en termes de division tronquée intégrée
auto const I = rT >= 0 ? 0 : (d > 0 ? 1 : -1);
auto const qE = qT - I;
auto const rE = rT + I * d;
assert(D == d * qE + rE);
assert(abs(rE) < abs(d));
assert(signum(rE) != -1);
Avec la division euclidienne, le signe du reste est toujours positif .