Operacja modulo jest kolejnym wątkiem programistycznym stanowiącym podstawy absolutne. Poza dodawaniem, odejmowaniem, mnożeniem i dzieleniem, jest także wyznaczanie reszty z dzielenia które wcale nie jest rzadziej wykorzystywane w kodzie. Uwierz mi!
Tweet |
MODULO PRZYDA CI SIĘ W WIELU RÓŻNYCH SYTUACJACH
Modulo w matematyce oznacza wyznaczanie reszty z dzielenia. Na przykład gdy podzielimy 5 przez 2, to wynik wyjdzie nam: 2 reszty 1. Kiedy podzielimy 4 przez 6, to wynikiem będzie: 0 reszty 4. To co jest po słowie "reszty", wyznacza nam operacja modulo. W kodzie źródłowym oznaczamy ją znakiem procent (%) i stawiamy go pomiędzy dwoma argumentami całkowitoliczbowymi (niektóre języki programowania zezwalają na wyznaczenie reszty z liczb zmiennoprzecinkowych, a nawet z liczb ujemnych!). Nikogo nie powinno dziwić dlaczego jest to operator binarny (operator przyjmujący dwa operandy) ;).
Zasada jest taka, że kiedy pierwszy operand jest mniejszy od drugiego (np. 4 % 6), to reszta z dzielenia zawsze będzie równa pierwszemu operandowi. Kiedy jest wprost przeciwnie, to od wyniku odejmujemy tyle wartości pierwszych operandów, ile "zmieściło się" jako całych i zwracamy pozostałą część "fragmentaryczną". Istnieje też taki wzór na resztę z dzielenia:
a % b = a - ⌊a / b⌋*b : b ≠ 0
Od "a" odejmujemy podłogę z ilorazu wyrazów "a" i "b", a wynik podłogi mnożymy przez wyraz "b". Jak ktoś ma problemy, to może to sobie spokojnie wyliczyć ;).
Trzeba koniecznie mieć pojęcie jak ta reszta "funkcjonuje" i co ma wpływ na wynik. Wyznaczanie reszty z dzielenia (modulo) działa w ten sposób, że nigdy nie opuszcza przedziału <0; N), gdzie N oznacza wartość drugiego argumentu. Biorąc za przykład drugi argument równy 6, to gdy przypiszemy za pierwszy operand parę kolejnych liczb naturalnych, to zobaczymy pewną zależność:
Operacja | Reszta z dzielenia |
0 % 6 | 0 |
1 % 6 | 1 |
2 % 6 | 2 |
3 % 6 | 3 |
4 % 6 | 4 |
5 % 6 | 5 |
6 % 6 | 0 |
7 % 6 | 1 |
8 % 6 | 2 |
9 % 6 | 3 |
10 % 6 | 4 |
11 % 6 | 5 |
Widzicie to? W momencie, gdy pierwszy argument "zrówna się" z drugim, to wynik jest zapętlany i "liczony od nowa", co jak najbardziej zgadza się z intuicyjnym spojrzeniem na wystający ułamek. Operacja modulo dzięki temu "trzymaniu się w ryzach" przedziałowych, bardzo się przydaje w rozwiązywaniu wielu problemów i piszę to całkowicie poważnie. Można na przykład elegancko inkrementować indeks tablicy, tak aby w momencie wyjścia poza jej zakres, był liczony od zera łącząc resztę z dzielenia, z dodawaniem:
int index = (index + 1) % N;
A pamiętacie grę "Snake" i moment, gdy wąż przechodząc przez prawą granicę ekranu nagle pojawiał się z lewej strony? To jest nic innego jak modulo!
int x = (x + snake.direction.x) % BOARD_WIDTH;
Piszę bardzo abstrakcyjnie, ale prostymi słowy tak to można zaprogramować.
CHCIAŁ(A)BYM MIEĆ JAKIŚ WPŁYW NA TEN PRZEDZIAŁ
Dobrze Cię rozumiem. Wtedy trzeba połączyć wyznaczanie reszty z dzielenia razem z przesunięciem o N liczb, po prostu dodając do tego składnik:
(a % b) + 1
co sprawi, że teraz wynik przyjmie wartość z przedziału <1; N>.
To wszystko co miałem do przekazania. Jeśli jeszcze nie umiecie wyliczać reszty z dzielenia w głowie, nauczcie się jak najprędzej. To ułatwi Wam potem programowanie różnych implementacji wymagających użycia operacji modulo. Zrozum, nie przepisuj!