Matematyka dyskretna Arytmetyka
Transkrypt
Matematyka dyskretna Arytmetyka
Matematyka dyskretna
Arytmetyka
Andrzej Szepietowski
1
System dziesiȩtny
Najpowszechniej używanym sposobem przedstawiania liczb naturalnych jest system dziesiȩtny,
gdzie na przyklad zapis:
178
przedstawia liczbȩ skladaja̧ca̧ siȩ z jednej setki, siedmiu dziesia̧tek i ośmiu jedności. Możemy to
zapisać w postaci:
178 = 1 · 100 + 7 · 10 + 8 · 1,
albo inaczej:
178 = 1 · 102 + 7 · 101 + 8 · 100 .
Tak wiȩc w systemie dziesiȩtnym kolejne cyfry oznaczaja̧ wspólczynniki przy kolejnych potȩgach
liczby dziesiȩć, zaczynaja̧c od najwiȩkszej, a kończa̧c na najmniejszej potȩdze. Mówimy, że liczba
dziesiȩć jest podstawa̧ lub baza̧ systemu dziesiȩtnego. W systemie dziesiȩtnym używamy dziesiȩciu
cyfr:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
a zapis:
dr dr−1 . . . d1 d0
oznacza liczbȩ:
dr · 10r + dr−1 · 10r−1 + . . . + d1 · 101 + d0 · 100 ,
która̧ możemy też zapisać w postaci:
r
X
di · 10i ,
(1)
(2)
i=0
gdzie di sa̧ cyframi należa̧cymi do zbioru {0, . . . , 9}.
Liczby można też zapisywać w systemach z inna̧ baza̧. Jeżeli za bazȩ systemu wybierzemy liczbȩ
b, to potrzebujemy b cyfr, a zapis:
dr dr−1 . . . d1 d0
oznacza w systemie z baza̧ b liczbȩ:
dr · br + dr−1 · br−1 + . . . + d1 · b1 + d0 · b0 ,
która̧ możemy też zapisać w postaci:
r
X
di · b i .
i=0
1
(3)
(4)
2
System dwójkowy
W informatyce bardzo ważnym systemem jest system dwójkowy (binarny), gdzie podstawa̧ jest
liczba 2 i gdzie mamy tylko dwie cyfry, 0 i 1 (cyfry w systemie dwójkowym nazywa siȩ bitami).
Zapis:
dr dr−1 . . . d1 d0
oznacza liczbȩ:
dr · 2r + dr−1 · 2r−1 + . . . + d1 · 21 + d0 · 20
lub:
r
X
di · 2 i .
i=0
Na przyklad, zapis 110 oznacza w systemie dwójkowym liczbȩ:
1 · 22 + 1 · 2 1 + 0 · 2 0 ,
czemu w systemie dziesiȩtnym odpowiada:
4 + 2 = 6.
Podobnie zapis:
1101101
oznacza w systemie dziesiȩtnym liczbȩ:
64 + 32 + 8 + 4 + 1 = 109.
W poniższej tabeli przedstawiono kilkanaście kolejnych liczb w postaci dwójkowej i dziesiȩtnej, a w
nastȩpnej — kilkanaście pierwszych potȩg liczby 2 w postaci dwójkowej i dziesiȩtnej.
dwójkowy
0
1
10
11
100
101
110
111
1000
1001
1010
1011
1100
1101
1110
1111
10000
dziesiȩtny
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
potȩga
0
1
2
3
4
5
6
7
8
9
10
3
dwójkowy
1
10
100
1000
10000
100000
1000000
10000000
100000000
1000000000
10000000000
dziesiȩtny
1
2
4
8
16
32
64
128
256
512
1024
Zwiȩkszanie liczby o jeden
Algorytm zwiȩkszania liczby o jeden. Aby zwiȩkszyć o jeden liczbȩ zapisana̧ w systemie
dwójkowym:
• wskazujemy na ostatni bit,
• powtarzamy, co nastȩpuje:
jeżeli wskazany bit jest zerem, to zamieniamy go na jedynkȩ i kończymy algorytm,
jeżeli jest on równy jeden, to zamieniamy go na zero i wskazujemy nastȩpny bit w lewo;
jeżeli nie ma nastȩpnego bitu w lewo, to stawiamy jedynkȩ na pocza̧tku liczby i kończymy
algorytm.
Mówia̧c inaczej, szukamy pierwszego zera od prawej strony, zamieniamy go na jedynkȩ, a wszystkie
jedynki stoja̧ce za nim zamieniamy na zera. Na przyklad, liczba o jeden wiȩksza od liczby
100100111
to
100101000.
Jeżeli liczba nie zawiera zer, tylko same jedynki, to zamieniamy te jedynki na zera i stawiamy
jedynkȩ na pocza̧tku. Na przyklad, po liczbie
11111
jest liczba
100000.
Zauważmy, że podobnie dziala algorytm zwiȩkszania o jeden liczb w systemie dziesiȩtnym (lub
dowolnym innym systemie). Szukamy pierwszej od prawej cyfry różnej od dziewia̧tki (najwiȩkszej
cyfry w systemie), zwiȩkszamy tȩ cyfrȩ o jeden, a wszystkie stoja̧ce za nia̧ dziewia̧tki zamieniamy
na zera.
3
4
Porównywanie liczb
Algorytm porównywania liczb. Aby stwierdzić, która z dwóch liczb jest wiȩksza, postȩpujemy
w nastȩpuja̧cy sposób:
• jeżeli zapisy liczb nie sa̧ tej samej dlugości, to wiȩksza̧ jest liczba z dluższym zapisem (zakladamy
tu, że zapis liczby różnej od zera nie ma zer na pocza̧tku),
• jeżeli zapisy liczb sa̧ równej dlugości, to porównujemy bit po bicie od lewej strony do prawej:
jeżeli bity sa̧ takie same, to przechodzimy do nastȩpnego bitu w prawo,
jeżeli bity sa̧ różne, to kończymy i stwierdzamy, że wiȩksza jest ta liczba, która ma
wiȩkszy bit na tej pozycji,
• jeżeli wszystkie bity sa̧ takie same, to porównywane liczby sa̧ równe.
Na przyklad:
1011010 > 1010101.
Powyższe liczby sa̧ tej samej dlugości i maja̧ takie same trzy pierwsze bity, a różnia̧ siȩ dopiero
czwartym bitem — czwarty bit pierwszej liczby (1) jest wiȩkszy od czwartego bitu drugiej liczby
(0).
5
Operacje arytmetyczne w systemie dwójkowym
Operacje dodawania, mnożenia, odejmowania i dzielenia w systemie dwójkowym można wykonywać
podobnie do tak zwanych szkolnych pisemnych dzialań arytmetycznych w systemie dziesiȩtnym.
Dzialania w systemie dwójkowym sa̧ prostsze, ponieważ mamy tu tylko dwie cyfry, 0 i 1, i prostsze
sa̧ operacje na pojedynczych cyfrach.
Zacznijmy od tabliczki dodawania i mnożenia. Wygla̧daja̧ one tak:
+
0
1
0
0
1
1
1
10
*
0
1
0
0
0
1
0
1
Przypuśćmy, że chcemy dodać dwie liczby w postaci dwójkowej. Zakladamy tu, że obie liczby sa̧
tej samej dlugości. Jeżeli nie sa̧, to krótsza̧ z nich uzupelniamy na pocza̧tku zerami.
Algorytm dodawania. Aby dodać dwie liczby w postaci binarnej:
dr dr−1 . . . d0 ,
er er−1 . . . e0 ,
dla kolejnych pozycji i od 0 do r obliczamy bit sumy s i oraz ci — tak zwany bit przeniesienia do
nastȩpnej pozycji:
4
• najpierw obliczamy s0 oraz c0 :
s0 = d 0 + e 0
(mod 2)
(czyli s0 jest reszta̧ z dzielenia d0 + e0 przez 2),
c0 = d 0 e0 ,
• nastȩpnie po kolei, dla każdego i od 1 do r, obliczamy i-ty bit sumy wedlug wzoru:
si = di + ei + ci−1
(mod 2),
a bit ci jest jedynka̧, jeżeli co najmniej dwa spośród bitów d i , ei oraz ci−1 sa̧ jedynkami,
• na końcu obliczamy najbardziej znacza̧cy bit sumy:
sr+1 = cr .
Wynikiem dodawania jest liczba
sr+1 sr . . . s0
(może siȩ zdarzyć, że sr+1 = 0).
Na przyklad, dodawanie liczb 10101 i 111 wygla̧da nastȩpuja̧co:
1
0
1
1
1
1
1
+
0
1
0
1
1
0
Aby odja̧ć od siebie dwie liczby w systemie dwójkowym, odejmujemy bit po bicie od prawej do lewej,
a w przypadku gdy trzeba odja̧ć bit wiȩkszy od mniejszego, ,,pożyczamy” dwójkȩ z nastȩpnej (w
lewo) pozycji (szczególy algorytmu pozostawiono jako ćwiczenie). Na przyklad, odejmowanie liczb
10101 i 111 wygla̧da nastȩpuja̧co:
1
0
1
1
1
−
1
0
1
1
1
1
0
Aby pomnożyć dwie liczby, mnożymy pierwsza̧ liczbȩ przez poszczególne cyfry drugiej liczby, a
wyniki podpisujemy pod spodem odpowiednio przesuniȩte wzglȩdem siebie. Każdy kolejny wynik
jest przesuniȩty o jedna̧ kolumnȩ w lewo. Nastȩpnie sumujemy te iloczyny. Oto przyklad mnożenia
liczb 10101 i 101:
1
1
0
0
1
1
0
1
0
1
0
0
0
0
1
5
1
1
1
0
1
0
0
0
0
0
1
1
1
0
1
Zauważmy, że pomnożenie liczby w postaci dwójkowej przez 2 oznacza dopisanie jednego zera na
końcu liczby. Podobnie pomnożenie przez i-ta̧ potȩgȩ liczby 2 oznacza dopisanie na końcu liczby i
zer. Na przyklad:
1101101
pomnożone przez
1000
daje wynik
1101101000.
Również dzielenie wykonuje siȩ podobnie jak w systemie dziesiȩtnym. Na przyklad:
1
1
1
0
1
0
1
1
1
0
1
1
0
0
0
1
1
1
0
0
1
1
1
0
0
0
0
1
1
0
:
1
0
1
Jeżeli liczba jest podzielna przez 2, to ma w postaci binarnej zero na końcu, a jeżeli dzieli siȩ przez
i-ta̧ potȩgȩ dwójki, to ma na końcu i zer. Podzielenie liczby przez 2 oznacza skreślenie w jej postaci
binarnej jednego zera z końca. Na przyklad:
1010011000
podzielone przez 2 daje:
101001100.
6
Zamiana systemu
Zastanówmy siȩ teraz, jak przechodzić od jednego sposobu przedstawiania liczby do drugiego.
Ponieważ bȩdziemy używać różnych systemów zapisu liczb, wiȩc zapis w systemie z baza̧ b oznaczymy przez:
(dr dr−1 . . . d1 d0 )b .
Bȩdziemy rezygnować z tego zapisu, jeżeli nie bȩdzie wa̧tpliwości, jakiego systemu używamy. Przedyskutujmy to na przykladach. Aby przedstawić liczbȩ
(110101)2
w postaci dziesiȩtnej, korzystamy ze wzoru 3:
(110101)2 = 1 · 25 + 1 · 24 + 0 · 23 + 1 · 22 + 0 · 21 + 1 · 20 ,
6
i wykonujemy wszystkie rachunki w systemie dziesiȩtnym:
(110101)2 = 1 · 32 + 1 · 16 + 0 · 8 + 1 · 4 + 0 · 2 + 1 · 1 = 32 + 16 + 4 + 1 = (53) 10 .
Podobnie możemy postȩpować przy zamianie w odwrotna̧ stronȩ, z systemu dziesiȩtnego na dwójkowy.
Najpierw korzystamy ze wzoru 1:
(53)10 = 5 · 101 + 3 · 100 ,
nastȩpnie przedstawiamy cyfry i podstawȩ systemu 10 w postaci dwójkowej i wykonujemy wszystkie
dzialania w systemie dwójkowym:
(53)10 = (101)2 · (1010)2 + (11)2 = (110010)2 + (11)2 = (110101)2 .
Ten sposób zamiany liczb z postaci dziesiȩtnej na dwójkowa̧ jest analogiczny do sposobu, w jaki
wyżej zamienialiśmy liczby z postaci dwójkowej na dziesiȩtna̧. Bylby to naturalny sposób dla kogoś,
kto swobodnie liczy w systemie dwójkowym. Sposób ten ma tȩ wadȩ, że wolno dziala. Zobaczymy
na przykladach dwa szybsze algorytmy zamiany postaci liczby z dziesiȩtnej na dwójkowa̧.
Weźmy liczbȩ 178. Pierwszy sposób polega na tym, że wyszukujemy najwiȩksza̧ potȩgȩ liczby
2, która jeszcze jest mniejsza od naszej liczby (w przykladzie 128 = 2 7 ), nastȩpnie odejmujemy tȩ
potȩgȩ od naszej liczby i z różnica̧ postȩpujemy tak samo. Na końcu mamy liczbȩ w postaci sumy
potȩg dwójki. W naszym przykladzie wygla̧da to tak:
178 = 128 + 50 = 128 + 32 + 18 = 128 + 32 + 16 + 2.
Teraz już latwo zapisać nasza̧ liczbȩ w postaci dwójkowej:
(178)10 = (10110010)2 .
Drugi sposób polega na kolejnym dzieleniu liczby w sposób calkowity przez 2 i zapamiȩtywaniu
reszt z dzielenia. Reszty te zapisane w odwrotnej kolejności tworza̧ zapis binarny liczby. Na
przyklad, weźmy znowu liczbȩ 178. W poniższej tabeli przedstawiono kolejne ilorazy i reszty.
liczba
178
89
44
22
11
5
2
1
iloraz
89
44
22
11
5
2
1
0
Reszty zapisane w odwrotnej kolejności:
10110010,
7
reszta
0
1
0
0
1
1
0
1
tworza̧ binarny zapis liczby (178) 10 .
Poprawność dzialania tego algorytmu wynika z faktu, że jeżeli podzielimy liczbȩ
x=
r
X
di · 2 i
i=0
przez 2, to reszta z dzielenia wyniesie d 0 , a iloraz calkowitoliczbowy wyniesie:
r
X
di · 2i−1 ,
i=1
nastȩpne dzielenie przez 2 da resztȩ d 1 oraz iloraz:
r
X
di · 2i−2 ,
i=2
i tak dalej.
Ostatni sposób można latwo uogólnić na algorytm zamiany liczb z systemu dziesiȩtnego na
system z inna̧ baza̧ b. Należy tylko dzielić przez b. Jeżeli chcemy, na przyklad, przedstawić liczbȩ
60 w systemie trójkowym, to dzielimy ja̧ kolejno przez 3 i spisujemy reszty z dzielenia:
liczba
60
20
6
2
iloraz
20
6
2
0
reszta
0
2
0
2
W wyniku otrzymamy:
(60)10 = (2020)3 .
7
Ulamki
Przypomnijmy najpierw krótko, jak przedstawia siȩ ulamek w systemie dziesiȩtnym. Na przyklad,
0.234
oznacza:
2 · 10−1 + 3 · 10−2 + 4 · 10−3 .
Użyliśmy kropki do oddzielania czȩści calkowitej od ulamkowej. Jest to czȩsto używany w informatyce sposób, stosowany miȩdzy innymi w jȩzyku Pascal.
Ogólniej, zapis:
0.d1 d2 . . . dr
oznacza liczbȩ:
d1 · 10−1 + d2 · 10−2 + . . . + dr · 10−r ,
8
która̧ możemy też zapisać w postaci:
r
X
di · 10−i .
i=1
Podobnie możemy zapisywać ulamki w systemie dwójkowym. Jedyna różnica polega na tym, że w
systemie binarnym podstawa̧ potȩg jest dwójka i że używamy tylko dwóch cyfr, 0 i 1. Tak wiȩc w
systemie dwójkowym zapis:
0.d1 d2 . . . dr
oznacza liczbȩ:
d1 · 2−1 + d2 · 2−2 + . . . + dr · 2−r ,
lub inaczej:
r
X
di · 2−i .
i=1
Na przyklad:
(0.1)2 = (0.5)10 ,
(0.11)2 = (0.75)10 ,
(0.101)2 = (0.625)10 .
W poniższej tabeli przedstawiono kilka pierwszych ujemnych potȩg liczby 2 w systemie dwójkowym
i dziesiȩtnym.
2−1
2−2
2−3
2−4
2−5
2−6
8
(0.1)2
(0.01)2
(0.001)2
(0.0001)2
(0.00001)2
(0.000001)2
(0.5)10
(0.25)10
(0.125)10
(0.0625)10
(0.03125)10
(0.015625)10
System szesnastkowy
W informatyce używa siȩ też systemu szesnastkowego, gdzie podstawa̧ jest liczba 16. Do systemu
szesnastkowego potrzebujemy szesnastu cyfr. Zwykle używa siȩ nastȩpuja̧cych ,,cyfr”:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.
W poniższej tabeli zestawiono cyfry systemu szesnastkowego z odpowiadaja̧cymi im liczbami w
systemie dwójkowym i dziesiȩtnym.
9
szesnastkowy
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
dwójkowy
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
dziesiȩtny
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Liczby w systemie szesnastkowym poprzedza siȩ zwykle (na przyklad w jȩzyku Pascal) znakiem
dolara $. I tak zapis $A1 oznacza liczbȩ w systemie szesnastkowym, która w systemie dziesiȩtnym
ma poniższa̧ postać:
$A1 = 10 · 16 + 1 = (161)10 .
Dziȩki temu, że 16 jest potȩga̧ dwójki, prosta jest zamiana postaci liczby z systemu dwójkowego
na szesnastkowy, i na odwrót. Przy zamianie z systemu szesnastkowego na dwójkowy wystarczy
zamieniać kolejne cyfry przedstawienia na grupy odpowiednich czterech bitów wedlug powyższej
tabeli. Na przyklad liczba, która w systemie szesnastkowym wygla̧da tak:
$A91,
w systemie dwójkowym ma postać:
1010|1001|0001.
Przy zamianie z postaci dwójkowej na postać szesnastkowa̧ postȩpujemy odwrotnie. Zastȩpujemy
grupy po cztery bity pojedynczymi cyframi. Na przyklad:
(1110|0011|1011|0000) 2 = $E3B0.
Jeżeli liczba cyfr w postaci dwójkowej nie dzieli siȩ przez 4, to uzupelniamy ja̧ zerami na pocza̧tku.
Na przyklad:
(110|1111|0110|0010) 2 = (0110|1111|0110|0010)2 = $6F 62.
W ten sposób możemy używać zapisu szesnastkowego do zwiȩzlego przedstawiania dlugich cia̧gów
bitów.
9
Reprezentacja liczb w komputerze
W jȩzyku Pascal każda zmienna ma swój typ, który jest deklarowany na pocza̧tku programu.
Sposób przechowywania wartości zmiennej zależy od jej typu.
10
10
Integer
Zmienne typu integer przechowywane sa̧ w dwóch bajtach. Jeden bajt (ang. byte) zawiera osiem
bitów, tak wiȩc wartość zmiennej typu integer przechowywana jest w szesnastu bitach. Pierwszy
bit oznacza znak. Jeżeli jest on zerem, to liczba jest dodatnia, jeżeli jedynka̧, to ujemna.
Jeżeli liczba jest dodatnia, to pozostale piȩtnaście bitów stanowi binarny zapis tej liczby. Na
przyklad liczba 15 jest przechowywana jako:
0000|0000|0000|1111.
Najwiȩksza̧ liczbȩ dodatnia̧, jaka̧ można przechować w zmiennej typu integer, jest:
0111|1111|1111|1111,
czyli zero i piȩtnaście jedynek. Jest to:
215 − 1 = (32767)10 .
Liczby ujemne sa̧ przechowywane w tak zwanym systemie uzupelnieniowym. Liczba ujemna o
wartości bezwzglȩdnej x jest przedstawiana jako liczba:
216 − x
w postaci binarnej. Na przyklad liczba −1 jest przedstawiona jako:
1111|1111|1111|1111,
czyli szesnaście jedynek. A liczba −3 jako:
1111|1111|1111|1101.
Najmniejsza liczba ujemna, która̧ można zmieścić do zmiennej typu integer, to:
1000|0000|0000|0000,
czyli jedynka i piȩtnaście zer, która koduje liczbȩ:
−215 = (−32768)10 .
W jȩzyku Pascal nie ma żadnego zabezpieczenia przed przekroczeniem maksymalnego lub minimalnego zakresu liczb typu integer. Jeżeli, na przyklad, do liczby 32767, która jest przechowywana
jako:
0111|1111|1111|1111,
dodamy jedynkȩ, to otrzymamy:
1000|0000|0000|0000,
która koduje liczbȩ −32768, i komputer nie zakomunikuje tego przekroczenia.
11
11
Real
Liczby typu real sa̧ zapisywane w dwóch notacjach:
• stalopozycyjnej,
• zmiennopozycyjnej.
Liczby w notacji stalopozycyjnej to, na przyklad:
0.10,
11.023,
12.0,
czyli notacja dziesiȩtna. Zwróćmy uwagȩ, że kropka oddziela czȩść calkowita̧ liczby od czȩści
ulamkowej.
W notacji zmiennopozycyjnej liczba przedstawiona jest w postaci:
mEc,
gdzie m jest mantysa̧, liczba̧ w postaci dziesiȩtnej z przedzialu 1 ≤ m < 10 lub −10 < m ≤ −1, a
c, zwana cecha̧, jest liczba̧ calkowita̧. Zapis mEc oznacza liczbȩ:
m · 10c .
W poniższej tabeli mamy kilka liczb w postaci stalo- i zmiennopozycyjnej.
4837.92
0.034
−12.0
4.83792E3
3.4E − 2
−1.2E1
Sposób przechowywania wartości zmiennych typu real jest skomplikowany i nie bȩdzie przedstawiony szczególowo.
12
Inne typy calkowite
W jȩzyku Pascal, oprócz integer, można używać innych typów calkowitych; sa̧ to:
• shortint, zawiera liczby calkowite z przedzialu od −128 do 127,
• byte, zawiera liczby calkowite z przedzialu od 0 do 255,
• word, zawiera liczby calkowite z przedzialu od 0 do 65535,
• longint, zawiera liczby calkowite z przedzialu od −2147483648 do 2147483647.
Elementy typu byte i shortint przechowywane sa̧ w jednym bajcie (osiem bitów) pamiȩci, typu
word — w dwóch bajtach, a typu longint — w czterech bajtach pamiȩci. Liczby typu shortint i
longint moga̧ być dodatnie lub ujemne i sa̧ zapamiȩtywane w postaci uzupelnieniowej z pierwszym
bitem oznaczaja̧cym znak (podobnie jak liczby typu integer). Elementy typu byte i word moga̧ być
tylko dodatnie i sa̧ przechowywane w postaci dwójkowej.
12
13
Wyrażenia arytmetyczne w jȩzyku Pascal
W jȩzyku Pascal wyrażeniami arytmetycznymi sa̧ stale liczbowe, na przyklad:
234,
−123,
0.123,
−23.45,
3.21E − 5,
oraz zmienne typów liczbowych (np. integer lub real). Wyrażenia można także budować za pomoca̧
operatorów arytmetycznych i nawiasów. Jeżeli U oraz W sa̧ dwoma wyrażeniami arytmetycznymi,
to wyrażeniami arytmetycznymi sa̧ także:
U+W, U-W, U*W, U/W, (U), U div V, U mod V.
Gwiazdka ∗ reprezentuje tutaj znak mnożenia, a operacje div oraz mod to iloraz i reszta z dzielenia
calkowitoliczbowego (sa̧ one opisane dokladnie w rozdziale o teorii liczb).
Na przyklad, wyrażeniami arytmetycznymi sa̧:
-(2-3)/2+7*4, (2-3)/(3*2), 7 div 2, 7 mod 2.
Jeżeli x oraz y sa̧ zmiennymi liczbowymi, to wyrażeniami arytmetycznymi sa̧ także:
2*x, x*x-2/y.
Dla danego wyrażenia możemy obliczyć jego wartość. Robi siȩ to wedlug zwyklych regul znanych
ze szkoly. Najpierw oblicza siȩ wyrażenia w nawiasach, potem mnożenie i dzielenie (od lewej do
prawej), a na końcu dodawanie i odejmowanie (od lewej do prawej).
14
Poszukiwania binarne (binary search)
Znana jest gra w dwadzieścia pytań. W tej grze za pomoca̧ dwudziestu pytań, na które odpowiedzia̧
może być ,,tak” lub ,,nie”, należy odgadna̧ć pomyślana̧ przez przeciwnika rzecz. Zobaczymy, jak
można wykorzystać binarny system zapisu liczb do opracowania strategii wygrywaja̧cej w tej grze.
Najpierw uprośćmy nieco tȩ grȩ. Zalóżmy, że możemy zadać tylko cztery pytania i że odgadujemy liczbȩ naturalna̧ x ze zbioru:
A = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}.
Wtedy należy zadać nastȩpuja̧ce cztery pytania:
• Czy liczba x należy do zbioru A1 = {8, 9, 10, 11, 12, 13, 14, 15}?
• Czy x należy do zbioru A2 = {4, 5, 6, 7, 12, 13, 14, 15}?
• Czy x należy do zbioru A3 = {2, 3, 6, 7, 10, 11, 14, 15}?
• Czy x należy do zbioru A4 = {1, 3, 5, 7, 9, 11, 13, 15}?
Dlaczego te cztery pytania wystarcza̧? Sprawa stanie siȩ jasna, jeżeli przedstawimy liczby w postaci
binarnej. Każda̧ za pomoca̧ czterech bitów (z zerami na pocza̧tku). Wtedy nasz zbiór wygla̧da tak:
A = { 0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111,
1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111}.
A pytania wygla̧daja̧ teraz tak:
13
• Czy x należy do zbioru A1 = {1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111}?
• Czy x należy do zbioru A2 = {0100, 0101, 0110, 0111, 1100, 1101, 1110, 1111}?
• Czy x należy do zbioru A3 = {0010, 0011, 0110, 0111, 1010, 1011, 1110, 1111}?
• Czy x należy do zbioru A4 = {0001, 0011, 0101, 0111, 1001, 1011, 1101, 1111}?
Zauważmy, że zbiór A1 zawiera wszystkie liczby z pierwszym bitem równym jedynce, w A 2 sa̧
wszystkie liczby z drugim bitem równym jedynce, i tak dalej. Tak wiȩc nasze pytania sa̧ w rzeczywistości pytaniami o kolejne bity odgadywanej liczby. Na przyklad w pierwszym pytaniu pytamy,
czy pierwszy bit odgadywanej liczby jest jedynka̧.
Ale można do tych pytań podejść inaczej. Najpierw dzielimy zbiór na polowy: na liczby mniejsze
od ośmiu i na liczby wiȩksze lub równe ośmiu, i pytamy, do której polowy należy odgadywana liczba
(dokladniej pytamy, czy liczba należy do górnej polowy). Po uzyskaniu odpowiedzi mamy dwa razy
wȩższy przedzial poszukiwań. Przypuśćmy, że odgadywana̧ liczba̧ jest 11. W drugim etapie dzielimy
przedzial
{8, 9, 10, 11, 12, 13, 14, 15}
na polowy, górna̧:
{12, 13, 14, 15}
i dolna̧:
{8, 9, 10, 11}
i pytamy, do której polowy należy szukana liczba. Po drugiej odpowiedzi przedzial poszukiwań jest
już cztery razy krótszy. Po dwóch kolejnych pytaniach przedzial zawȩża siȩ do jednej liczby. Drugi
sposób jest calkowicie równoważny pierwszemu, tutaj też pytamy o kolejne bity i otrzymujemy takie
same odpowiedzi.
Potrzeba cztery razy kolejno dzielić zbiór na polowy, aby z pocza̧tkowej dlugości 16 przejść
na końcu do dlugości 1. A ile trzeba podzialów, jeżeli na pocza̧tku mamy n = 2 k elementów?
Po pierwszym podziale nasz zbiór bȩdzie mial dlugość 2 k−1 , po drugim 2k−2 , a po i-tym 2k−i .
Jak widać, potrzeba k = log 2 n kolejnych podzialów, aby dojść do 1. Tak wiȩc jeżeli mamy do
dyspozycji 20 pytań, to możemy odnaleźć jedna̧ spośród 2 20 liczb calkowitych z przedzialu od 0 do
220 − 1 = 1 048 575.
15
Waga
Zobaczymy teraz, jak można wykorzystać trójkowy system zapisu liczb. W systemie trójkowym
podstawa̧ jest liczba 3, mamy trzy cyfry {0, 1, 2} i zapis
dr dr−1 . . . d1 d0
oznacza liczbȩ:
dr · 3r + dr−1 · 3r−1 + . . . + d1 · 31 + d0 · 30 ,
14
lub inaczej:
r
X
di · 3 i .
i=0
Wyobraźmy sobie wagȩ szalkowa̧. Na jednej szalce, lewej, kladziemy jakiś przedmiot do zważenia,
a nastȩpnie na obu szalkach kladziemy odważniki. Jeżeli waga jest w równowadze, to ważony przedmiot ma wagȩ równa̧ sumie (nominalów) odważników polożonych na prawej szalce minus suma
odważników polożonych na lewej szalce, obok ważonego przedmiotu. Na przyklad, jeżeli na prawej
szalce leża̧ odważniki o ciȩżarach 2 i 20 gramów, a na lewej odważniki o wadze 4 i 5 gramów, to
przedmiot waży 13 = (20 + 2) − (5 + 4) gramów.
Interesuja̧ce nas pytanie brzmi: jakie powinny być nominaly poszczególnych odważników, aby
można bylo zważyć każdy ciȩżar o wadze od 1 do N , przy jak najmniejszej liczbie odważników.
Zakladamy, że ważymy tylko przedmioty o calkowitych wagach.
Rozpatrzmy najpierw przyklad czterech odważników o wagach:
c1 , c 2 , c 3 , c 4 .
Ile różnych ciȩżarów można odważyć za pomoca̧ czterech odważników? Ponieważ każdy odważnik
może siȩ znajdować na prawej lub lewej szalce, lub na stole, to mamy 3 4 = 81 różnych polożeń
odważników. Wśród tych polożeń jest takie, gdzie wszystkie cztery odważniki leża̧ na stole (wtedy ważymy zerowy ciȩżar). Ponadto jeżeli odważniki leża̧ na szalkach i odważaja̧ ciȩżar W , to
zamieniwszy polożenia odważników na szalkach (odważniki z lewej przekladamy na prawa̧ szalkȩ,
i na odwrót), bȩdziemy odważać ciȩżar −W . Tak wiȩc spośród 81 ulożeń odważników na szalkach
tylko
81 − 1
= 40
2
odważa jakiś dodatni ciȩżar. Oczywiście może siȩ zdarzyć, że dwa różne polożenia odważników
odważaja̧ ten sam ciȩżar.
Interesuje nas, czy istnieja̧ takie cztery odważniki, za pomoca̧ których można odważyć każdy
ciȩżar od 1 do 40. Odpowiedź na to pytanie jest pozytywna. Istnieja̧ takie cztery odważniki, sa̧ to:
1,
3,
9,
27.
Zauważmy, że nominaly odważników to cztery pierwsze potȩgi liczby 3. Każde ulożenie tych
odważników odważa ciȩżar:
W = d3 · 27 + d2 · 9 + d1 · 3 + d0 · 1,
(5)
lub inaczej:
W = d 3 · 33 + d2 · 32 + d1 · 31 + d0 · 30 ,
gdzie di = 1, jeżeli odważnik o nominale 3i leży na prawej szalce, di = −1, jeżeli leży na lewej, i
di = 0, jeżeli leży na stole.
Zobaczymy, że każda̧ liczbȩ od 1 do 40 można przedstawić w postaci 5. Zauważmy, że jeżeli do
ciȩżaru W dodamy:
40 = 27 + 9 + 3 + 1,
15
to otrzymamy:
W + 40 = (d3 + 1) · 33 + (d2 + 1) · 32 + (d1 + 1) · 31 + (d0 + 1) · 30 .
Jeżeli teraz oznaczymy:
ei = di + 1,
dla 0 ≤ i ≤ 3, to otrzymamy:
W + 40 = e3 · 33 + e2 · 32 + e1 · 31 + e0 · 30 .
(6)
Zauważmy, że każde ei jest teraz ze zbioru {0, 1, 2} i wzór 6 przedstawia rozwiniȩcie liczby W + 40
w systemie trójkowym, a ponieważ W jest z przedzialu od 1 do 40, to W + 40 jest z przedzialu od
41 do 80 i można ja̧ przedstawić za pomoca̧ czterech cyfr w systemie trójkowym.
Powyższy wywód sugeruje algorytm odszukiwania polożenia odważników dla danego ciȩżaru W .
Algorytm ważenia. Chca̧c zważyć ciȩżar W z przedzialu od 1 do 40:
• przedstawiamy liczbȩ W + 40 w systemie trójkowym: W + 40 = (e 3 e2 e1 e0 )3 ,
• od każdej cyfry odejmujemy jedynkȩ: d i = ei − 1,
• postać (d3 d2 d1 d0 ) określa polożenie poszczególnych odważników wedlug zasady:
jeżeli di = 1, to odważnik o nominale 3i należy polożyć na prawej szalce,
jeżeli di = −1, to na lewej,
jeżeli di = 0, to na stole.
Spróbujmy zważyć ciȩżar W = 20 gramów. W rozdziale o zamianie systemu obliczyliśmy, że
liczba 60 = 20 + 40 w systemie trójkowym ma postać:
(60)10 = (2020)3 ,
czyli:
60 = 2 · 27 + 0 · 9 + 2 · 3 + 0 · 1.
Odejmujemy teraz jedynkȩ od każdej cyfry i otrzymujemy:
(11̄11̄).
Tutaj 1̄ oznacza −1. Mamy wiȩc:
20 = 27 − 9 + 3 − 1.
Metodȩ opisana̧ wyżej można uogólnić na wiȩksza̧ liczbȩ odważników. Jeżeli mamy N odważników
o nominalach:
1, 3, . . . , 3N −1 ,
to możemy odważyć każdy ciȩżar W z przedzialu od 1 do (3 N − 1)/2. Należy rozwina̧ć liczbȩ
W + (3N − 1)/2 w systemie trójkowym, a nastȩpnie od każdej cyfry rozwiniȩcia odja̧ć jedynkȩ.
16
16
Zadania
1. Zwiȩksz o jeden nastȩpuja̧ce liczby zapisane w postaci dwójkowej: a) 11010011;
2. Porównaj nastȩpuja̧ce pary liczb: a) 110011, 110100;
b) 111111.
b) 11010, 1110.
3. Dodaj (odejmij, pomnóż) w postaci dwójkowej nastȩpuja̧ce pary liczb: a) 110011, 110100;
b) 11010, 1110.
4. Napisz dokladny algorytm odejmowania dwóch liczb w postaci dwójkowej.
5. Liczby 81, 126 przedstaw w postaci dwójkowej. Jak bȩda̧ one reprezentowane w komputerze
jako stale typu integer (byte, word)?
6. Nastȩpuja̧ce liczby przedstaw w postaci dwójkowej: 6.75, 5.625, $B1, $FF.
7. Nastȩpuja̧ce liczby przedstaw w postaci trójkowej: 80, 120.
8. Nastȩpuja̧ce liczby w postaci dwójkowej, 10001101, 100101, przedstaw w postaci: a) dziesiȩtnej,
b) szesnastkowej.
9. Opisz algorytm zamiany ulamka z postaci dziesiȩtnej na postać dwójkowa̧.
10. Ile maksymalnie pytań z odpowiedziami TAK/NIE trzeba zadać, aby odgadna̧ć liczbȩ z
przedzialu od 0 do 100 000?
11. Jak należy ulożyć na szalkach odważniki o nominalach 1, 3, 9, 27, aby odważyć ciȩżar: a) 35,
b) 29?
17