Aquí hay una nueva respuesta a una pregunta anterior, basada en este artículo de Microsoft Research y sus referencias.
Tenga en cuenta que desde C11 y C ++ 11 en adelante, la semántica de se divha convertido en un truncamiento hacia cero (ver [expr.mul]/4). Además, para Ddividir por d, C ++ 11 garantiza lo siguiente sobre el cociente qTy el 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));
donde se signumasigna a -1, 0, +1, dependiendo de si su argumento es <, ==,> que 0 (consulte estas preguntas y respuestas para obtener el código fuente).
Con división truncada, el signo del resto es igual al signo del dividendoD , es decir -1 % 8 == -1. C ++ 11 también proporciona una std::divfunción que devuelve una estructura con miembros quotyrem acuerdo con la división truncada.
Hay otras definiciones posibles, por ejemplo, la denominada división en suelo se puede definir en términos de la división truncada incorporada.
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 división en suelo, el signo del resto es igual al signo del divisor.d . En lenguajes como Haskell y Oberon, hay operadores integrados para la división por suelo. En C ++, necesitaría escribir una función usando las definiciones anteriores.
Otra forma más es la división euclidiana , que también se puede definir en términos de la división truncada incorporada.
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 división euclidiana, el signo del resto es siempre positivo .