Dlaczego mod (%) jest podstawowym operatorem matematycznym w wielu językach programowania?

17

Czy istnieje powód, historyczny lub inny, dlaczego operator modułu jest częścią małego zestawu standardowych operatorów w, jak się wydaje, wielu językach? ( +, -, *, /oraz %, dla Java i C, z **w Ruby i Python).

Dziwne wydaje się umieszczanie modu jako „podstawowego” (nie pukać, używam go dużo, ale używam również potęgowania, wartości bezwzględnej, podłogi / sufitu lub innych - wydają się tak samo użyteczne i konieczne). Czy była to stara decyzja podjęta w jakiejś specyfikacji, z której korzystają Java, C, Ruby i Python, czy też język, z którego wszyscy pochodzą? O ile wiem, większość dialektów Lisp obejmuje tylko +, -, /i *.

Na początku zastanawiałem się, czy mod był szczególnie łatwy do wdrożenia na poziomie binarnym (czy miałoby to nawet znaczenie, jeśli chodzi o decyzje dotyczące tego, co powinno być „podstawowym” operatorem, a co nie?), Ale wydaje się, że tak nie jest. Czy jest to o wiele bardziej powszechnie stosowane w programowaniu niż myślę?

Eli Rose - REINSTATE MONICA
źródło

Odpowiedzi:

20

Jestem pewien, że jest to powszechne, ponieważ wiele architektur procesora implementuje modulusjako drugie wyjście instrukcji dzielenia liczb całkowitych.

Nie pamiętam, aby był obecny w procesorach z lat 70. (6800, 8080, Z80, 1604 itd.), Ale w latach 80. miały go Intel 8086 i 8088, a także Motorola 6809.

Architektura instrukcji PDP-11 określiła DIVtworzenie ilorazu i reszty od początku (1970), chociaż instrukcje MUL i DIV nie były obecne we wczesnych projektach, ale mogły być w przejrzysty sposób emulowane przez „pułapkę niezaimplementowaną instrukcji” i implementowane za pomocą handler, który trochę się zakręcił. Prawdopodobnie funkcja PDP-11 zachęciły bardzo pierwszą edycję języku C zapewniającego %funkcję. (Czy zauważyłeś kiedyś, że znak procentu zawiera ukośnik? To sprawia, że ​​jest to sprytny wybór dla operatora związanego z działem.)

Obecność samego modułu Cmoże prawdopodobnie wyjaśnić jego obecność we wszystkich współczesnych językach. Cma bardzo dużą rodzinę potomków i poza tym był dość wpływowy.

wallyk
źródło
3
Wpływ +1 C na prawie każdy język inny niż LISP od wczesnych lat siedemdziesiątych nie może być przeceniony.
Ross Patterson,
8

Wiele języków programowania ma operator „reszty”, który może być wykorzystywany jako operator modułu, gdy oba operandy są dodatnie; wspomniany operator jest często nazywany operatorem „modułu”, ponieważ jest to jego podstawowe zastosowanie. Języki mają na ogół takiego operatora, ponieważ sprzęt działający na wielu platformach sprzętowych automatycznie dostarcza resztę podczas wykonywania podziału, a obliczenie pozostałej części lub modułu za pomocą innych środków byłoby znacznie trudniejsze.

Nie znam historii wsparcia sprzętowego dla podpisanego podziału; wiele procesorów od lat zapewnia sprzęt, który może automatycznie wykonywać podpisany podział z zastrzeżeniem zasady, że jeśli a / b da (q, r), to -a / b lub a / -b da (-q, -r), ale Nie jestem pewien przypadków użycia, w których podział przy użyciu tej reguły jest szczególnie pomocny. W prawie każdym przypadku, w którym użyłem podziału na liczbę całkowitą lub operacji „modułu” na wartościach ujemnych, chciałem zaokrąglić w kierunku ujemnej nieskończoności na podziale i operacji na prawdziwym module (takiej, że (a + b) / b zawsze równa (a / b) +1 i (a + b)% b zawsze będzie równa% b.). Ponieważ operatorzy nie działają w ten sposób, konieczne jest przetestowanie znaku dywidendy i użycie innego kodu, gdy „ s negatywny - zasadniczo neguje jakąkolwiek korzyść z posiadania podpisanej instrukcji podziału. Ciekawi mnie, w jakim celu pomocna jest sprzętowa obsługa podziału podpisów.

Wracając do pierwotnego pytania, operator modułu jest często przydatny w sytuacjach, w których pewne rzeczy mają się zdarzać okresowo, albo w przestrzeni (np. Współrzędne graficzne), albo w czasie. Na przykład, jeśli chce się, aby zdarzenie miało miejsce co 15 sekund, czas do następnego zdarzenia wyniesie 15 - ((czas_czasu - czas_wystąpienia)% 15), przy założeniutime_of_an_occurrencetime_now , że nie jest większy niż . Gdyby time_of_an_occurrencebyły większe niż time_now, operator modułu mógłby nadal używać tej samej formuły, pod warunkiem że odejmowanie nie przepełniło się, ale operator reszty będzie wymagał innej formuły.

supercat
źródło
3
Z tego powodu Haskell ma dwa operatory: remdla reszty i moddla modułu o opisanych właściwościach.
Ingo
@Complicatedseebio: Szczególnie zabawne jest to, że często nazywane jest operatorem modułu, ponieważ zwykle jest używane do obliczania modułu, nawet jeśli wymaga to kodu m = number % base; if (m < 0) m+=base;. Nie wiem, czy kiedykolwiek widziałem jakikolwiek kod, który korzystałby z tego, że pozostały operator q = n/d; if (n%d < 0) q+=1;byłby negatywny, z wyjątkiem być może , który w każdym razie mógłby być napisany lepiej na inne sposoby.
supercat
3

Moduł jest ściśle związany z teorią grup i pierścieni, które są bardzo podstawowymi teoriami matematycznymi.

Potęgowanie jest tylko trzecią operacją dodawania, mnożenia, potęgowania, tetracji (i to jest sekwencja nieskończona). Staje się to ważne głównie przy liczbach zespolonych, które są rzadsze w arytmetyce komputerowej. Jedno szczególne potęgowanie jest jednak obsługiwane jawnie: 2 n jest zwykle zapisywane jako 1<<n, ponieważ komputery są dość binarne.

Podłoga i sufit są naprawdę rzadkie w porównaniu: obowiązują tylko przy konwersji z ℝ na ℤ. (zmiennoprzecinkowy do liczby całkowitej). Podobnie absjest związany z odwzorowaniem z ℤ na ℕ

MSalters
źródło
ℤ są liczbami całkowitymi (a ℕ jest podzbiorem liczb całkowitych), musisz oznaczać od ℝ do ℤ.
Joni
@Joni: Naprawiono dwa mieszane przykłady.
MSalters
0

Przepraszam, ale ryzykuję, że zamienimy to w grę „Call My Bluff”. Myślę, że prawdziwa odpowiedź na to pytanie jest dość prosta:

Mod pozwala na precyzyjne obliczenia w „nie dziesiętnych” ilościach i jednostkach, takich jak daty, czas, jardy, cale, uncje itp. W obliczeniach dziesiętnych zapewnia również programistom pracę z dokładnością liczbową wykraczającą poza tę zapewnianą przez sprzęt maszyny. Ma to ogromną liczbę zastosowań, od bardzo małych (np. Obliczenia kwantowe) do bardzo dużych (np. Odkrywanie nowych liczb pierwszych).

Ważne jest, aby zrozumieć, że nazywaliśmy te rzeczy komputerami bez powodu. Czasami potrzebujemy ich, aby dali nam prawidłową odpowiedź!


źródło
Ta odpowiedź nie ma sensu ... Jaki jest związek między używaniem „mod” a używaniem różnych jednostek?