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ę?
źródło
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żeniu
time_of_an_occurrence
time_now
, że nie jest większy niż . Gdybytime_of_an_occurrence
był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.źródło
rem
dla reszty imod
dla modułu o opisanych właściwościach.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 operatorq = 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.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
abs
jest związany z odwzorowaniem z ℤ na ℕźródło
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