Oto nowa odpowiedź na stare pytanie, oparta na artykule Microsoft Research i zawartych w nim odniesieniach.
Zauważ, że począwszy od C11 i C ++ 11, semantyka programu div
stała się obcięta do zera (zobacz [expr.mul]/4
). Ponadto, w przypadku D
dzielenia przez d
, C ++ 11 gwarantuje następujące informacje o ilorazie qT
i pozostałej częścirT
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));
gdzie signum
mapuje do -1, 0, +1, w zależności od tego, czy jego argument jest <, ==,> niż 0 (zobacz ten Q&A dla kodu źródłowego).
W przypadku dzielenia obciętego znak reszty jest równy znakowi dywidendyD
, tj -1 % 8 == -1
. C ++ 11 zapewnia również std::div
funkcję, która zwraca strukturę ze składowymi quot
i rem
według obciętego podziału.
Możliwe są inne definicje, np. Tak zwany podział ze stropem może być zdefiniowany za pomocą wbudowanego podziału obciętego
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));
W przypadku dzielenia liczbowego znak reszty jest równy znakowi dzielnikad
. W językach takich jak Haskell i Oberon istnieją wbudowane operatory dzielenia liczbowego. W C ++ trzeba by napisać funkcję przy użyciu powyższych definicji.
Jeszcze innym sposobem jest podział euklidesowy , który można również zdefiniować za pomocą wbudowanego podziału obciętego
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);
W przypadku podziału euklidesowego znak reszty jest zawsze dodatni .