Berikut adalah jawaban baru untuk pertanyaan lama, berdasarkan makalah Riset Microsoft ini dan referensi di dalamnya.
Perhatikan bahwa dari C11 dan C ++ 11 dan seterusnya, semantik div
telah dipotong ke arah nol (lihat [expr.mul]/4
). Selanjutnya, untuk D
dibagi dengan d
, C ++ 11 menjamin hal-hal berikut tentang hasil bagi qT
dan sisarT
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));
di mana signum
dipetakan ke -1, 0, +1, tergantung pada apakah argumennya <, ==,> dari 0 (lihat Tanya Jawab ini untuk kode sumber).
Dengan pembagian terpotong, tanda sisa sama dengan tanda pembagianD
, yaitu -1 % 8 == -1
. C ++ 11 juga menyediakan std::div
fungsi yang mengembalikan struct dengan anggota quot
dan rem
menurut pembagian terpotong.
Ada definisi lain yang mungkin, misalnya yang disebut divisi berlantai dapat didefinisikan dalam istilah divisi terpotong bawaan
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));
Dengan pembagian berlantai, tanda sisa sama dengan tanda pembagid
. Dalam bahasa seperti Haskell dan Oberon, terdapat operator builtin untuk divisi lantai. Di C ++, Anda perlu menulis fungsi menggunakan definisi di atas.
Namun cara lain adalah divisi Euclidean , yang juga dapat didefinisikan dalam istilah divisi terpotong bawaan
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);
Dengan pembagian Euclidean, tanda sisanya selalu positif .