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 divtornou-se truncada para zero (consulte Recursos[expr.mul]/4 ). Além disso, para Ddividido por d, C ++ 11 garante o seguinte sobre o quociente qTe 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 signummapeia 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::divfunção que retorna uma estrutura com membros quoterem 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 .