นี่คือคำตอบใหม่สำหรับคำถามเก่าโดยอ้างอิงจากเอกสารวิจัยของ 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 หรือไม่ (ดูQ&A นี้สำหรับซอร์สโค้ด)
ด้วยส่วนที่ถูกตัดทอนสัญญาณของส่วนที่เหลือจะมีค่าเท่ากับสัญญาณของเงินปันผล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);
ที่มีการแบ่งยุคลิดสัญลักษณ์ของที่เหลือที่เป็นบวกเสมอ