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 D
diviso per d
, C ++ 11 garantisce quanto segue sul quoziente qT
e 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 signum
mappato 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::div
funzione che restituisce una struttura con membri quot
e in rem
base 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 .