Aqui está uma nova resposta a uma pergunta antiga, com base neste documento de pesquisa da Microsoft e nas referências nele contidas.
Observe que de C11 e C ++ 11 em diante, a semântica de div
tornou-se truncada para zero (consulte Recursos[expr.mul]/4
). Além disso, para D
dividido por d
, C ++ 11 garante o seguinte sobre o quociente qT
e o restorT
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));
onde signum
mapeia para -1, 0, +1, dependendo se seu argumento é <, ==,> do que 0 (veja este Q&A para o código-fonte).
Com a divisão truncada, o sinal do resto é igual ao sinal do dividendoD
, ou seja -1 % 8 == -1
. C ++ 11 também fornece uma std::div
função que retorna uma estrutura com membros quot
erem
acordo com a divisão truncada.
Existem outras definições possíveis, por exemplo, a chamada divisão de piso pode ser definida em termos da divisão truncada embutida
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));
Com a divisão com piso, o sinal do resto é igual ao sinal do divisord
. Em linguagens como Haskell e Oberon, existem operadores embutidos para divisão por piso. Em C ++, você precisa escrever uma função usando as definições acima.
Ainda outra forma é a divisão euclidiana , que também pode ser definida em termos da divisão truncada embutida
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);
Com a divisão euclidiana, o sinal do resto é sempre positivo .