Ecco una nuova risposta a una vecchia domanda, basata su questo documento di Microsoft Research e sui riferimenti in esso contenuti.
Si noti che da C11 e C ++ 11 in poi, la semantica di divè diventata troncamento verso zero (vedere [expr.mul]/4). Inoltre, per Ddiviso per d, C ++ 11 garantisce quanto segue sul quoziente qTe sul 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));
dove viene signummappato a -1, 0, +1, a seconda che il suo argomento sia <, ==,> o 0 (vedere questa domanda e risposta per il codice sorgente).
Con divisione troncata, il segno del resto è uguale al segno del dividendoD , cioè -1 % 8 == -1. C ++ 11 fornisce anche una std::divfunzione che restituisce una struttura con membri quote in rembase alla divisione troncata.
Sono possibili altre definizioni, ad esempio la cosiddetta divisione floored può essere definita in termini di divisione troncata incorporata
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));
Con la divisione in piani, il segno del resto è uguale al segno del divisored . In lingue come Haskell e Oberon, ci sono operatori incorporati per la divisione floored. In C ++, dovresti scrivere una funzione utilizzando le definizioni di cui sopra.
Ancora un altro modo è la divisione euclidea , che può anche essere definita in termini di divisione troncata incorporata
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);
Con la divisione euclidea, il segno del resto è sempre positivo .