ทำไม mod (%) เป็นผู้ดำเนินการทางคณิตศาสตร์ขั้นพื้นฐานในภาษาการเขียนโปรแกรมหลายภาษา?


17

มีเหตุผลประวัติศาสตร์หรืออย่างอื่นทำไมผู้ประกอบการโมดูลัสเป็นส่วนหนึ่งของผู้ประกอบการมาตรฐานขนาดเล็กในสิ่งที่ดูเหมือนว่าหลายภาษา? (+, -, *, /และ%สำหรับ Java และ C ด้วย**ใน Ruby และ Python)

ดูเหมือนจะแปลกที่จะรวม mod เป็น "พื้นฐาน" (ไม่ต้องเคาะมันฉันใช้มันมากมาย แต่ฉันยังใช้การยกกำลัง, ค่าสัมบูรณ์, พื้น / เพดานหรืออื่น ๆ - ดูเหมือนว่ามีประโยชน์และจำเป็น) นี่เป็นการตัดสินใจแบบเก่าในข้อกำหนดบางอย่างที่ Java, C, Ruby และ Python ติดตามหรือภาษาที่สืบทอดมาทั้งหมดหรือไม่ เท่าที่ผมสามารถบอกได้มากที่สุดภาษาเสียงกระเพื่อมรวมเฉพาะและ+, -, /*

ในตอนแรกฉันสงสัยว่า mod นั้นง่ายต่อการนำไปใช้ในระดับไบนารี่ (หรือว่าจะทำให้เกิดความแตกต่างเกี่ยวกับการตัดสินใจเกี่ยวกับสิ่งที่ควรจะเป็นโอเปอเรเตอร์ "พื้นฐาน" และสิ่งที่ไม่ควร?) แต่ดูเหมือนว่า มันใช้กันทั่วไปในการเขียนโปรแกรมมากกว่าที่ฉันคิดหรือเปล่า?

คำตอบ:


20

ฉันแน่ใจว่าเป็นเรื่องปกติเพราะสถาปัตยกรรมของ CPU จำนวนมากนำไปใช้modulusเป็นเอาต์พุตที่สองของคำสั่งการหารจำนวนเต็ม

ฉันจำไม่ได้ว่ามันมีอยู่ในซีพียูยุค 1970 (6800, 8080, Z80, 1604, ฯลฯ ) แต่ในช่วงปี 1980 Intel 8086 และ 8088 รวมถึง Motorola 6809 ก็มีเช่นกัน

สถาปัตยกรรมการเรียนการสอน PDP-11 ระบุDIVการผลิตความฉลาดทางและส่วนที่เหลือจากจุดเริ่มต้น (1970) แม้ว่าคำสั่ง MUL และ DIV ไม่ได้มีอยู่ในการออกแบบในช่วงต้น แต่สามารถเลียนแบบโปร่งใสโดย "คำสั่งไม่ได้ดำเนินการกับดัก" ตัวจัดการที่ทำ twiddling เล็กน้อย อาจเป็นไปได้ว่าคุณสมบัติ PDP-11 สนับสนุนภาษา C รุ่นแรกที่ให้%คุณสมบัตินี้ (เคยสังเกตว่าเครื่องหมายเปอร์เซ็นต์มีเครื่องหมายทับหรือไม่ซึ่งทำให้เป็นตัวเลือกที่ชาญฉลาดสำหรับตัวดำเนินการที่เกี่ยวข้องกับแผนก)

การมีมอดุลัสอยู่Cคนเดียวอาจอธิบายได้ว่ามีอยู่ในทุกภาษาในปัจจุบัน Cมีตระกูลใหญ่มากและมีอิทธิพลค่อนข้างมาก


3
+1 C มีอิทธิพลต่อภาษาที่ไม่ใช่ LISP เกือบทุกภาษาตั้งแต่ต้นปี 1970 ไม่สามารถพูดเกินจริงได้
Ross Patterson

8

ภาษาโปรแกรมส่วนใหญ่มีตัวดำเนินการ "เศษเหลือ" ซึ่งอาจใช้เป็นตัวดำเนินการมอดุลัสเมื่อตัวถูกดำเนินการทั้งคู่เป็นค่าบวก ตัวดำเนินการดังกล่าวมักถูกเรียกว่าตัวดำเนินการ "โมดูลัส" เพราะนั่นคือการใช้งานหลัก ภาษาทั่วไปมีตัวดำเนินการดังกล่าวเนื่องจากฮาร์ดแวร์ส่วนของแพลตฟอร์มฮาร์ดแวร์ส่วนที่เหลือให้โดยอัตโนมัติเมื่อทำการแบ่งและคำนวณส่วนที่เหลือหรือโมดูลัสผ่านวิธีอื่นใดจะยากมาก

ฉันไม่ทราบประวัติความเป็นมาของการสนับสนุนฮาร์ดแวร์สำหรับการแบ่งเซ็นชื่อ ตัวประมวลผลจำนวนมากมีหลายปีที่มีฮาร์ดแวร์ที่สามารถทำการแบ่งส่วนที่เซ็นชื่อโดยอัตโนมัติภายใต้กฎว่าหาก a / b ให้ผลตอบแทน (q, r) ดังนั้น -a / b หรือ a / -b จะให้ผลตอบแทน (-q, -r) แต่ ฉันไม่แน่ใจกรณีการใช้งานที่การแบ่งใช้กฎนั้นมีประโยชน์อย่างยิ่ง ในเกือบทุกกรณีที่ฉันใช้การหารจำนวนเต็มหรือการดำเนินการ "โมดูลัส" กับค่าลบฉันต้องการการปัดเศษไปทางลบอินฟินิตี้ในการหารและการดำเนินการโมดูลัสจริง (เช่น + a) เท่ากับเสมอ (a / b) +1 และ (a + b)% b จะเท่ากับ a% b เสมอ) เนื่องจากผู้ประกอบการไม่ทำงานอย่างนั้นจึงจำเป็นต้องทดสอบเครื่องหมายการจ่ายเงินปันผลและใช้รหัสอื่นเมื่อมัน ' s เป็นลบ - ลบล้างผลประโยชน์ใด ๆ จากการมีคำสั่งหารที่ลงนามในตอนแรก ฉันอยากรู้ว่าจุดประสงค์ของการสนับสนุนการลงนามในฮาร์ดแวร์มีประโยชน์อย่างไร

กลับไปที่คำถามเดิมตัวดำเนินการโมดูลัสมักจะมีประโยชน์ในสถานการณ์ที่สิ่งต่าง ๆ ควรจะเกิดขึ้นเป็นระยะ ๆ ไม่ว่าจะเป็นในอวกาศ (เช่นพิกัดกราฟิก) หรือในเวลา ตัวอย่างเช่นถ้าใครอยากที่จะมีเหตุการณ์เกิดขึ้นทุก 15 วินาทีเวลาจนกว่าเหตุการณ์ต่อไปจะเป็น 15 - ((time_now - time_of_an_occurrence) 15%) สมมติว่าtime_of_an_occurrencetime_nowไม่เกิน ถ้าtime_of_an_occurrenceมากกว่าtime_nowตัวดำเนินการโมดูลัสสามารถใช้สูตรเดิมต่อไปได้หากการลบไม่ล้น แต่ตัวดำเนินการส่วนที่เหลือจะต้องใช้สูตรอื่น


3
ด้วยเหตุผลดังกล่าว Haskell มีตัวดำเนินการสองตัว: remส่วนที่เหลือและmodสำหรับมอดุลัสพร้อมคุณสมบัติที่คุณอธิบาย
Ingo

@Complicatedseebio: m = number % base; if (m < 0) m+=base;มีอะไรโดยเฉพาะอย่างยิ่งที่ตลกคือว่ามันมักจะเรียกว่าผู้ประกอบการโมดูลัสเพราะโดยทั่วไปจะใช้ในการคำนวณโมดูลัสแม้ในขณะที่ต้องใช้รหัสเช่น ฉันไม่ทราบว่าฉันเคยเห็นรหัสใด ๆ ที่ได้รับประโยชน์จากตัวดำเนินการส่วนที่เหลือจะเป็นค่าลบยกเว้นบางทีq = n/d; if (n%d < 0) q+=1;ซึ่งอาจจะเขียนได้ดีกว่าในกรณีอื่น
supercat

3

โมดูลัสมีความสัมพันธ์อย่างใกล้ชิดกับทฤษฎีกลุ่มและแหวนซึ่งเป็นทฤษฎีทางคณิตศาสตร์ขั้นพื้นฐานมาก

การยกกำลังเป็นเพียงการดำเนินการที่สามในการบวกลำดับการคูณการยกกำลังการเตต (และนั่นคือลำดับอนันต์) มันกลายเป็นสิ่งสำคัญส่วนใหญ่กับตัวเลขที่ซับซ้อนซึ่งหายากในคณิตศาสตร์คอมพิวเตอร์ การสนับสนุนการยกกำลังแบบใดแบบหนึ่งได้รับการสนับสนุนอย่างชัดเจนแม้ว่า: 2 nมักเขียนเป็น1<<nเนื่องจากคอมพิวเตอร์ค่อนข้างเป็นเลขฐานสอง

การเปรียบเทียบพื้นและเพดานนั้นหาได้ยากมาก: ใช้กับการแปลงจากℝถึงℤเท่านั้น (floating point เป็นจำนวนเต็ม) ในทำนองเดียวกันabsมีความเกี่ยวข้องกับการทำแผนที่จากℤถึงℕ


ℤเป็นจำนวนเต็ม (และℕเป็นเซตย่อยของจำนวนเต็ม) คุณต้องหมายถึงตั้งแต่ℝถึงℤ
Joni

@Joni: ผสมสองตัวอย่างคงที่
MSalters

0

ขออภัยที่มีความเสี่ยงในการเปลี่ยนเป็นเกม "Call My Bluff" ฉันคิดว่าคำตอบที่แท้จริงสำหรับคำถามนี้ค่อนข้างง่าย:

Mod ช่วยให้การคำนวณที่แม่นยำในปริมาณและหน่วย "ไม่ใช่ทศนิยม" เช่นวันที่, เวลา, หลา, นิ้ว, ออนซ์และอื่น ๆ ในการคำนวณเลขฐานสิบมันยังให้วิธีการสำหรับโปรแกรมเมอร์ในการทำงานกับความแม่นยำของตัวเลขที่เกินจากฮาร์ดแวร์ ของเครื่อง นี่มีแอปพลิเคชั่นจำนวนมากตั้งแต่ขนาดเล็กมาก (เช่นการคำนวณควอนตัม) จนถึงขนาดใหญ่มาก (เช่นการค้นหาหมายเลขเฉพาะใหม่ ๆ )

เป็นสิ่งสำคัญที่จะต้องเข้าใจว่าเราเรียกสิ่งเหล่านี้ด้วยเหตุผลทางคอมพิวเตอร์ บางครั้งเราต้องการพวกเขาเพื่อให้คำตอบที่ถูกต้อง!


คำตอบนี้ไม่สมเหตุสมผล ... การเชื่อมต่อระหว่างการใช้ "mod" กับการใช้หน่วยต่าง ๆ คืออะไร?
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.