Tại sao mod (%) là toán tử cơ bản trong nhiều ngôn ngữ lập trình?


17

Có một lý do, lịch sử hay nói cách khác, tại sao toán tử mô đun là một phần của một tập hợp nhỏ các toán tử tiêu chuẩn trong những gì có vẻ giống như nhiều ngôn ngữ? ( +, -, *, /%, đối với Java và C, với **Ruby và Python).

Có vẻ lạ khi bao gồm mod là "cơ bản" (không đánh bại nó, tôi sử dụng nó rất nhiều, nhưng tôi cũng sử dụng lũy ​​thừa, giá trị tuyệt đối, sàn / trần hoặc những thứ khác - chúng có vẻ hữu dụng và cần thiết). Đây có phải là một quyết định cũ được đưa ra trong một số đặc điểm kỹ thuật mà Java, C, Ruby và Python đều tuân theo hoặc một ngôn ngữ mà tất cả chúng đều có nguồn gốc từ? Theo như tôi có thể nói hầu hết các phương ngữ Lisp chỉ bao gồm +, -, /*.

Lúc đầu, tôi tự hỏi liệu mod có dễ thực hiện ở cấp nhị phân không (điều đó thậm chí có tạo ra sự khác biệt hay không, liên quan đến các quyết định về điều gì nên là toán tử "cơ bản" và điều gì không nên?) Nhưng dường như không phải vậy. Có phải nó chỉ được sử dụng phổ biến hơn nhiều trong lập trình hơn tôi nghĩ?

Câu trả lời:


20

Tôi chắc chắn rằng nó là phổ biến vì nhiều kiến ​​trúc CPU thực hiện modulusnhư một đầu ra thứ hai của lệnh chia số nguyên.

Tôi không nhớ nó có mặt trong các CPU của thập niên 1970 (6800, 8080, Z80, 1604, v.v.), nhưng đến thập niên 1980, Intel 8086 và 8088, cũng như Motorola 6809 đã có nó.

Kiến trúc lệnh PDP-11 được chỉ định DIVtạo ra thương số và phần còn lại từ đầu (1970), mặc dù các lệnh MUL và DIV không có trên các thiết kế ban đầu, nhưng có thể được mô phỏng trong suốt bởi một "bẫy không được thực hiện" và được thực hiện với một xử lý mà đã twiddling. Có lẽ tính năng PDP-11 đã khuyến khích phiên bản đầu tiên của ngôn ngữ C cung cấp %tính năng này. (Bạn có bao giờ nhận thấy dấu hiệu phần trăm có dấu gạch chéo trong đó không? Điều đó làm cho nó trở thành một lựa chọn thông minh cho một toán tử liên quan đến bộ phận.)

Sự hiện diện của mô-đun Cmột mình có lẽ có thể giải thích sự hiện diện của nó trong tất cả các ngôn ngữ hiện đại. Ccó một gia đình con cháu rất lớn và có ảnh hưởng khá lớn.


3
Ảnh hưởng của +1 C đối với hầu hết mọi ngôn ngữ không phải LISP kể từ đầu những năm 1970 không thể được nói quá.
Ross Patterson

8

Nhiều ngôn ngữ lập trình có toán tử "phần còn lại" có thể được sử dụng làm toán tử mô đun khi cả hai toán hạng đều dương; toán tử cho biết thường được gọi là toán tử "mô đun", vì đó là cách sử dụng chính của nó. Các ngôn ngữ thường có một toán tử như vậy bởi vì phần cứng phân chia của nhiều nền tảng phần cứng sẽ tự động cung cấp phần còn lại khi thực hiện phép chia và tính toán phần còn lại hoặc mô đun thông qua bất kỳ phương tiện nào khác sẽ khó khăn hơn nhiều.

Tôi không biết lịch sử hỗ trợ phần cứng cho bộ phận đã ký; nhiều bộ xử lý trong nhiều năm đã cung cấp phần cứng có thể tự động thực hiện phân chia đã ký theo quy tắc rằng nếu a / b mang lại (q, r), thì -a / b hoặc a / -b sẽ sinh ra (-q, -r), nhưng Tôi không chắc chắn về các trường hợp sử dụng trong đó phân chia sử dụng quy tắc đó đặc biệt hữu ích. Trong hầu hết mọi trường hợp tôi đã sử dụng các phép toán số nguyên hoặc các mô đun "mô đun" cho các giá trị âm, tôi đã muốn vòng vô cực theo chiều âm trên phép chia và một phép toán mô đun thực (như vậy (a + b) / b sẽ luôn luôn bằng (a / b) +1 và (a + b)% b sẽ luôn bằng a% b.). Bởi vì các nhà khai thác không hoạt động theo cách đó, nên cần phải kiểm tra dấu hiệu của cổ tức và sử dụng mã khác nhau khi nó ' s phủ định - về cơ bản phủ nhận bất kỳ lợi ích nào từ việc có một hướng dẫn phân chia đã ký ở vị trí đầu tiên. Tôi tò mò về mục đích hỗ trợ phân chia đã ký trong phần cứng thực sự hữu ích.

Quay trở lại câu hỏi ban đầu, toán tử mô đun thường hữu ích trong các tình huống trong đó một số điều được cho là xảy ra trên cơ sở định kỳ, hoặc trong không gian (ví dụ như tọa độ đồ họa) hoặc theo thời gian. Ví dụ: nếu một người muốn có một sự kiện xảy ra cứ sau 15 giây, thì thời gian cho đến sự kiện tiếp theo sẽ là 15 - ((time_now - time_of_an_occurrence)% 15), giả sử time_of_an_occurrencekhông lớn hơntime_now . Nếu time_of_an_occurrencelớn hơn time_now, một toán tử mô đun có thể tiếp tục sử dụng cùng một công thức với điều kiện phép trừ không tràn, nhưng toán tử còn lại sẽ yêu cầu một công thức khác.


3
Vì lý do đó, Haskell có hai toán tử: remcho phần còn lại và modcho mô đun với các thuộc tính bạn mô tả.
Ingo

@Complicatedseebio: Điều đặc biệt buồn cười là nó thường được gọi là toán tử mô đun vì nó thường được sử dụng để tính toán mô đun, ngay cả khi điều đó yêu cầu mã như thế nào m = number % base; if (m < 0) m+=base;. Tôi không biết rằng tôi đã từng thấy bất kỳ mã nào được hưởng lợi từ toán tử còn lại sẽ bị âm, ngoại trừ q = n/d; if (n%d < 0) q+=1;, trong mọi trường hợp, có thể được viết tốt hơn theo những cách khác.
supercat

3

Modulus liên quan chặt chẽ với lý thuyết nhóm và vòng, đó là những lý thuyết toán học rất cơ bản.

Phép lũy thừa chỉ là phép toán thứ ba trong phép cộng, nhân, lũy thừa, phép hóa (và đó là một chuỗi vô hạn). Nó trở nên quan trọng chủ yếu với các số phức, hiếm hơn trong số học máy tính. Một số mũ cụ thể được hỗ trợ rõ ràng, mặc dù: 2 n thường được viết là 1<<n, vì các máy tính khá nhị phân.

Sàn và trần thực sự rất hiếm khi so sánh: Chúng chỉ áp dụng khi chuyển đổi từ sang. (dấu phẩy động đến số nguyên). Tương tự, absđược liên kết với ánh xạ từ ℤ đến


Là các số nguyên (và là tập con của các số nguyên), bạn phải có nghĩa là từ ℝ đến.
Joni

@Joni: Hỗn hợp hai ví dụ, cố định.
MSalters

0

Xin lỗi, nhưng có nguy cơ biến điều này thành một trò chơi của "Call My Bluff" Tôi nghĩ rằng câu trả lời thực sự cho câu hỏi này khá đơn giản:

Mod cho phép tính toán chính xác với số lượng và đơn vị "không thập phân" như ngày, thời gian, thước, inch, ounce, v.v. Trong tính toán thập phân, nó cũng cung cấp một phương pháp để lập trình viên làm việc với độ chính xác số vượt quá mức được cung cấp bởi phần cứng của máy. Điều này có một số lượng lớn các ứng dụng từ rất nhỏ (ví dụ tính toán lượng tử) đến rất lớn (ví dụ: khám phá các số nguyên tố mới).

Điều quan trọng là phải hiểu rằng chúng tôi gọi những thứ này là máy tính vì một lý do. Đôi khi chúng ta cần họ cho chúng ta câu trả lời chính xác!


Câu trả lời này không có ý nghĩa gì ... Mối liên hệ giữa việc sử dụng "mod" và sử dụng các đơn vị khác nhau là gì ???
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.