Вот новый ответ на старый вопрос, основанный на этой исследовательской работе Microsoft и ссылках в ней.
Обратите внимание, что начиная с C11 и C ++ 11 и выше семантика div
стала усечением до нуля (см. [expr.mul]/4
). Кроме того, для D
, деленного на d
, C ++ 11 гарантирует следующее о частном qT
и остатке rT
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));
, где signum
отображается на -1, 0, +1, в зависимости от того, является ли его аргумент <, ==,> чем 0 (см. этот раздел вопросов и ответов для исходного кода).
При усеченном делении знак остатка равен знаку дивиденда D
, т. Е. -1 % 8 == -1
. C ++ 11 также предоставляет функцию std::div
, которая возвращает структуру с членами quot
и rem
в соответствии с усеченным делением.
Возможны и другие определения, например, так называемое этажное деление можно определить в терминах встроенного усеченного деления
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));
При настиленном делении знак остатка равен знаку делителя d
. В таких языках, как Haskell и Oberon, есть встроенные операторы для разделения по этажам. В C ++ вам нужно написать функцию, используя приведенные выше определения.
Еще одним способом является евклидово деление , которое также можно определить в терминах встроенного усеченного деления
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);
При евклидовом делении знак остатка всегда положительный .