II dvocas:

1) Konvertovati sledece zapise iz osnove u osnovu:

    45241 -->   (iz osnove 6 u osnovu 10)
    10210121201 --> (iz osnove 3 u osnovu 9) (primetiti da je 9 = 3 na kvadrat)
    59813 -->  (iz osnove 10 u osnovu 12, cifre 0,1,...,9,A,B)
    23412 -->  (iz osnove 5 u osnovu 7) (preko osnove 10)


2) Izracunati zbir sledecih brojeva:

    538715
   +431745   (osnova 9)
   -------

    4279A1
   +934A17   (osnova 11, cifre 0,1,...,9,A)
   -------

    AHGCD5
   +571FE9   (osnova 18, cifre 0,1,...,9,A,B,...,F,G,H)
   -------

   1203212
   2031103
   3010120
   2033321
   3211233
   2323323
 + 3032012   (osnova 4)
   -------
 

   101110101
   010111011
   101101101
   010111011
   110111011
  +010101010 (osnova 2)
   ---------

3) Izracunati razliku sledecih brojeva:

   46351632  (osnova 7)
  -26442514
   --------

   AB754FD
  -487FC1E   (osnova 16)
   -------

   1000101110 (osnova 2)
   0110101010 
   ----------

4) Pretpostaviti da je veliki ceo broj dat u sledecem obliku:

   typedef struct {
       unsigned c[1000];
       unsigned n;
       unsigned B;
   } Broj;

gde je c niz cifara (pocev od cifre najmanje tezine), n je broj 
cifara broja (ne veci od 1000) a B je osnova (B>=2). Napisati funkciju:

void ucitaj(Broj * b);

koja ucitava sa standardnog ulaza broj tako sto se prvo ucita osnova,
zatim broj cifara, a nakon toga cifre (pocev od cifre najvece tezine).
Cifre se unose tako sto se njihove vrednosti navedu razdvojene razmacima.
Npr, heksadekadni broj AB593 bi se unosio na sledeci nacin:

16
5
10 11 5 9 3

Napisati i funkciju:

void ispisi(Broj * b);

koja ispisuje na izlazu (u istom formatu kao i kod ucitavanja) broj.

5) Koristeci strukture podataka iz prethodnog zadatka, napisati funkciju:

void saberi(Broj * a, Broj * b, Broj * r);

koja sabira brojeve a i b i rezultat smesta u broj r. Pretpostaviti da
su brojevi a i b zadati u istoj osnovi. 

6) Koristeci strukture podataka iz prethodnog zadatka, napisati funkciju:

void oduzmi(Broj * a, Broj * b, Broj * r);

koja oduzima brojeve a i b i rezultat smesta u broj r. Pretpostaviti da
su brojevi a i b zadati u istoj osnovi. 

III dvocas:

7) Izracunati sledece proizvode:

BABA * DEDA = ? (osnova 16)
5725 * 7034 = ? (osnova 8)
10212 * 2112 = ? (osnova 3)
10011101 * 11101010 = ? (osnova 2)

8) Podeliti neoznacene brojeve:

673194 : 43 = ?  (osnova 8)
53AC1EF : 13 = ? (osnova 16)
10210121 : 21 = ? (osnova 3)
10010110111011 : 1101 = ? (osnova 2)

9) Napisati funkciju u C-u:

void saberi_sve(char ** x, unsigned n, unsigned b, char * r);

koja prihvata niz stringova x duzine n koji sadrze zapise neoznacenih
brojeva u osnovi b i sve ih sabira. Zbir treba smestiti u niz
karaktera na koji pokazuje r.

10) Napisati funkciju u C-u:

void pomnozi_brojem(char * x, unsigned b, unsigned y, char * r);

koja broj x zapisan u osnovi b mnozi brojem y (tipa unsigned). Rezultat
treba da bude zapisan u osnovi b i smesten u niz na koji pokazuje r.
NAPOMENA: ova funkcija je slicna funkciji pomnozi_cifrom() sa vezbi,
jedino sto sada broj y ne mora biti "cifra", vec moze biti broj proizvoljne
velicine (koji moze da stane u unsigned). Ovo malo komplikuje implementaciju,
zato sto prenos na sledecu poziciju moze biti visecifren.

11) Napisati funkciju u C-u:

void pomnozi(char * x, unsigned b1, char * y, unsigned b2, char * r);

koja mnozi broj x zapisan u osnovi b1 sa brojem y zapisanim u osnovi b2.
Rezultat treba da bude zapisan u osnovi b1 i smesten u niz na koji
pokazuje r. 
NAPOMENA: kako vrednosti cifara broja y vise ne moraju biti legitimne cifre
broja x, umesto funkcije pomnozi_cifrom() treba koristiti funkciju iz
zadatka 10). Sve ostalo bi trebalo da je slicno kao na vezbama.

12) Koristeci strukture podataka iz zadatka 4), napisati funkciju:

void pomnozi_cifrom(Broj * b, unsigned c, Broj * r);

koja broj b u datoj osnovi mnozi cifrom c i rezultat smesta u strukturu
na koju pokazuje r. 

13) Koristeci funkciju iz prethodnog zadatka, napisati funkciju:

void pomnozi(Broj * b1, Broj * b2, Broj * r);

koja mnozi brojeve b1 i b2 (koji su zadati u istoj osnovi) i vraca
proizvod preko pokazivaca r. 

14) Koristeci se strukturama podataka iz zadatka 4), implementirati deljenje u
proizvoljnoj osnovi B, tj. napisati funkciju:

void podeli(Broj * b1, Broj * b2, Broj * q, Broj * r);

koja deli brojeve b1 i b2 (koji su zadati u istoj osnovi) i vraca celobrojni
kolicnik q i ostatak pri deljenju r.

15) Napisati funkciju:

void konvertuj_unsigned_u_broj(unsigned v, unsigned B, Broj * r);

koja uzima neoznaceni broj v i formira zapis njegove vrednosti u osnovi B 
u obliku strukutre Broj iz zadatka 4). 

16) Napisati funkciju:

void konvertuj_zapis(Broj * b, unsigned B, Broj * r);

koja broj b zadat u nekoj osnovi b->B konvertuje u zapis u osnovi B i rezultat
vraca preko pokazivaca r. 

UPUTSTVO: Sada kada smo naucili mnozenje i deljenje u proizvoljnoj osnovi (i 
implementirali funkcije u zadacima 13) i 14), mozemo da vrsimo konverziju
zapisa izmedju proizvoljnih osnova. Jedan nacin je da se broj b zapisan u 
osnovi b->B "raspise" po definiciji kao:

unsigned n = b->n;

((...(0*b->B + b->c[n-1])*b->B + b->c[n-2])*b->B + b->c[n-3])....)*b->B + b->c[0],

a da se zatim sve operacije koje se ovde pojavljuju obave u osnovi B, pomocu
funkcija koje su napisane u zadacima 13) (mnozenje) i 5) (sabiranje). Da biste
ovo postigli, potrebno je da vrednosti koje se pojavljuju u gornjem izrazu, a
koje su tipa unsigned prethodno transformisete u strukturu Broj, zapisane u
osnovi B, a to mozete uraditi pomocu funkcije iz zadatka 15).

IV dvocas:

17) Napisati funkciju koja sabira n-to bajtne neoznacene cele brojeve:

void saberi_brojeve(void * x, void * y, void * s, unsigned * c, unsigned n);

pri cemu adrese x i y predstavljaju adrese najnizih bajtova odgovarajcih
sabiraka u memoriji, a broj n predstavlja duzinu sabiraka u bajtovima.
Zbir treba smestiti u memoriju pocev od adrese s. Prekoracenje treba 
smestiti u lokaciju na koju pokazuje c. 

NAPOMENA: Ova univerzalna funkcija bi trebalo da moze da se primeni na
sve celobrojne tipove, npr:

unsigned short x, y, s;
unsigned c;

saberi_brojeve(&x, &y, &s, &c, sizeof(unsigned short));

18) Sta radi sledeca funkcija:

void tajanstvena_funkcija(unsigned x, unsigned y, unsigned *p, unsigned *q)
{
  unsigned S, P;
  *q = 0;

  while(y)
    {
      S = x ^ y;
      P = x & y;

      x = S;

      if(P & 0x80000000)
        *q = 1;

      y = P << 1;
    }

  *p = x;
}

19) Napisati funkciju koja poredi neoznacene cele brojeve x i y. Funkcija 
treba da vrati -1 ako je x manje, 0 ako su jednaki, a 1 ako je x vece.
Funkcija treba da koristi bitovske operatore (ne sme da koristi operatore
<, >, ==, <=, >=). 


V dvocas:

20) Izracunati -x, ako je x dat u potpunom komplementu:
    
    54631 (osnova 10)
    11221 (osnova 3)
    AFC01 (osnova 16)

Koji su to (dekadni) brojevi?

21) Dekadni broj -745 zapisati u potpunom komplementu u sledecim osnovama:
    a) osnova 8, 4 cifre
    b) osnova 3, 7 cifre
    c) osnova 16, 3 cifre
    d) osnova 6, 5 cifre

22) Izvrsiti sledece operacije u potpunom komplementu:

    35402 + 44   (osnova 5)
    75633 - 275  (osnova 8)
    31201 - 2112 (osnova 4)
    01101110 + 11011 (osnova 2)


(U slucaju oduzimanja, uraditi zadatke na oba nacina, tj. direktnim
oduzimanjem, kao i sabiranjem sa suprotnim elementom).

23) Napisati funkcije za odredjivanje znaka, promenu znaka, sabiranje
i oduzimanje brojeva u potpunom komplementu u proizvoljnoj osnovi, gde su
brojevi zapisani pomocu stringova (kao na casu). 

VI dvocas

24) Pomnoziti brojeve u potpunom komplementu:

 a) BABA * DEDA  (osnova 16)
 b) 12035 * 77123 (osnova 8)
 c) 0012 * 2201  (osnova 3)

U svim slucajevima pokusati mnozenje uraditi na dva nacina:
 -- pomnoziti apsolutne vrednosti, a zatim po potrebi promeniti znak
 -- pomnoziti ih direktno (kao da su neoznaceni). U tom slucaju, rezultat
 ce biti u redu samo ako staje u n cifara (gde je n duzina zapisa cinilaca).

25) Podeliti brojeve u potpunom komplementu:

 a) 6431634 : 532  (osnova 7)
 b) 2013102 : 102  (osnova 4)

26) Pomnoziti binarne brojeve Butovim algoritmom:

  a) 01101110 * 11101110
  b) 10101101 * 01111001
  c) 11110011 * 10101110

27) Podeliti binarne brojeve (na bilo koji ispravan nacin):

  a) 10001100 / 11110101
  b) 10100011 / 00000111
  c) 00110111 / 11111110

28) Napisati funkciju koja prosiruje short u int, koristeci bitovske operatore
(tj. ne koristiti C-ovu konverziju).

29) Napisati funkciju koja koristeci bitovske operatore uporedjuje dva
podatka tipa int. Funkcija vraca 1 ako je prvi veci, 0 ako su jednaki a -1
ako je prvi manji od drugog. NAPOMENA: Nije dozvoljeno koristiti relacione
operatore ==, !=, <, >, i sl. nad celobrojnim podacima.

30) Modifikovati Butov algoritam tako da mnozi mnozenik tipa int sa mnoziocem 
tipa unsigned. UPUTSTVO: Razlika je samo u tumacenju najviseg bita mnozioca, koji
sada predstavlja pozitivnu vrednost, pa je na kraju potrebno jos jedno dodavanje
ukoliko je taj bit jedinica.

31) (Novembar 2014) Napisati funkciju:

void potpuni_komplement(int x, unsigned B, char * zapis);

koja za dati podatak tipa int (oznaceni ceo broj u binarnom zapisu)
i datu osnovu B >= 2, odredjuje zapis tog broja u potpunom 
komplementu u osnovi B, sa najmanjim mogucim brojem cifara. 

32) (Novembar 2014)  Napisati funkciju:

void potpuni_komplement(char * zapis, unsigned B, int * x);

koja za broj zapisan u obliku stringa zapis u potpunom komplementu
u osnovi B odredjuje odgovarajuci binarni zapis u potpunom komplementu
i smesta ga u podatak na koji pokazuje x (tipa int).

33) (Novembar 2013) Napisati funkciju koja mnozi
velike dekadne brojeve. Brojevi su dati strukturom:

typedef struct {
  unsigned d[1000];
  unsigned n;
} Number;

gde je n broj cifara datog broja, a d je niz koji sadrzi vrednosti dekadnih
cifara, pocev od cifre najmanje tezine. 

34) (Novembar 2014) Napisati funkciju:

int uporedi(char * x, char * y, unsigned B);

koja za dva oznacena broja u potpunom komplementu u osnovi B
predstavljenih stringovima odredjuje koji je veci. Funkcija
treba da vrati 1 ako je x > y, -1 ako je x < y, a 0 ako su
jednaki.

34a) (Novembar 2015) Napisati funkciju:

unsigned najmanja_osnova(int x, unsigned k);

koji odredjuje najmanju osnovu u kojoj se ceo broj x moze zapisati u
potpunom komplementu sa najvise k cifara.  

34b) (Novembar 2015) Napisati funkciju:

void apsolutna_razlika(char * x, char * y, unsigned B, char * rez);

koja izracunava |x - y|, pri cemu su x i y oznaceni celi brojevi
zapisani u potpunom komplementu u osnovi B. 

VII dvocas

35) Konvertovati sledece zapise:

43.12 (osnova 10) u osnovu 8
1101.00101 (osnova 2) u osnovu 5 (preko osnove 10, ili direktno)
2013.1311 (osnova 4) u osnovu 10
ACF85.38D (osnova 16) u osnovu 2 (direktno)

36) Predstaviti date vrednosti u IEEE-754 jednostruke tacnosti (float):

-23.54
0.0047
13.05
45331.09

37) Dati su 32-bitni zapisi u IEEE-754 formatu:

A345D000
590F3000
7ACB3520

Odrediti vrednosti realnih brojeva koji su predstavljeni tim zapisima.

38) Za vrednosti iz zadatka 36) odrediti njihov zapis u dvostrukoj tacnosti (double).

39) Napisati funkciju koja, pomocu bitovskih operatora, konvertuje:
    a) double u float
    b) int u float
    c) int u double (kolokvijum 2012)
    d) float u int (kolokvijum 2012)
    e) double u int

40) Napisati funkciju koja mnozi float podatak sa 2^k, koristeci bitovske
    operatore.

41) Napisati funkciju koja oduzima dva float podatka.

42) Napisati funkciju koja uporedjuje dva float podatka. Funkcija treba da
    vrati -1 ako je prvi manji, 1 ako je prvi veci, 0 ako su jednaki
    (Kolokvijum 2011).

43) Napisati funkciju koja sabira dva double podatka. Dozvoljeno je 
    koristiti bitovske operatore, kao i aritmeticke operatore nad celobrojnim
    tipovima. (kolokvijum 2011).

44) Napisati funkciju koja deli dva float-a, koristeci bitovske
   operatore. Dozvoljeno je koristiti aritmeticke operatore nad
   celobrojnim tipovima (kolokvijum 2012).

45) Napisati funkciju koja vrsi realno deljenje dva unsigned-a i smesta rezultat
    u float (npr. kolicnik neoznacenih brojeva 5 i 2 je float sa vrednoscu 2.5). Deljenje
    izvrsiti direktno, tj. bez prethodne konverzije u float. Dozvoljeno je koriscenje
    aritmetickih operacija nad celobrojnim tipovima (kolokvijum 2012).

46) Napisati funkciju koja za dati double podatak ispituje da li sadrzi
"okruglu" vrednost, tj. da li je njegova vrednost ceo broj (npr. 2.0 jeste
takav, dok 2.3 nije). (ispit, februar 2014)

47) Napisati funkciju koja za dati pozitivan float podatak vraca njen ceo deo (kao
unsigned) i razlomnljeni deo (kao float). Npr. za broj 5.7 treba da vrati 
5 i 0.7. (ispit, jun 2014)

48) Napisati funkciju koja za dati pozitivan float podatak i dati unsigned
podatak odredjuje njihov zbir, koristeci bitovske operatore. Dozvoljeno je
koristiti i aritmeticke operatore nad celim brojevima. (ispit, septembar 2014).


ASEMBLER:

NAPOMENA ZA SVE ZADATKE: U svakom zadatku treba napisati i main() funkciju
u C-u koja ucitava podatke, poziva funkciju i ispisuje rezultat na izlazu.
Funkciju koja se trazi u zadatku pisati u asembleru. Savet: gde god je 
zgodno, pisati pomocne funkcije (takodje u asembleru), pa ih pozivati.
Ovakva dekompozicija ce pojednostaviti glavni algoritam.

49) (Ispit, januar 2015)
   a) Napisati IA-32 asemblersku funkciju:
      unsigned dupliraj(unsigned x);
   koja za dati broj x vraca broj koji nastaje tako sto se u njegovom
   dekadnom zapisu duplira svaka njegova parna cifra. Na primer, za
   broj x = 56672 treba da vrati 56666722. Pretpostaviti da ce
   dobijeni broj stati u unsigned. Napisati i C-program koji testira
   ovu funkciju.
   b) Napisati IA-32 asemblersku funkciju:
     unsigned izbaci(unsigned x);
   koja za dati broj x vraca broj koji nastaje tako sto se u njegovom
   dekadnom zapisu svaka sekvenca uzastopnih jednakih parnih cifara
   zamenjuje jednom takvom cifrom. Npr. za x = 244116642 treba da
   vrati 2411642, a za x= 26664433 treba da vrati 26433.

50) Napisati asemblersku funkciju int prebroj_proste(int m, int n) koja broji 
koliko ima prostih brojeva u intervalu [m, n]. 
51) Napisati funkciju int savrsen(int n) koja ispituje da li je dati broj
n > 0 savrsen. Za broj kazemo da je savrsen ako je jednak zbiru svojih 
pravih delilaca. Funkcija treba da vrati 1 ako je broj n savrsen, a 0
ako nije (na primer, broj 6 je savrsen jer je 1 + 2 + 3 = 6).
52) Napisati funkciju koja racuna zbir dekadnih cifara datog nenegativnog
celog broja.
53) Napisati funkciju koja racuna "tajni broj" datog broja. Tajni broj 
nekog broja x se dobija na sledeci nacin: kreira se sekvenca brojeva
x0, x1, ... takva da je x0 = x, a x_{i+1} se dobija od broja x_{i} tako
sto se saberu parovi susednih dekadnih cifara x_{i} i tako se dobiju
cifre broja x_{i+1} (npr. od broja x_{i} = 54125 se dobija broj x_{i+1} = 9537, 
jer je  5 + 4 = 9, 4 + 1 = 5, 1 + 2 = 3, 2 + 5 = 7). Ukoliko je zbir nekog
para susednih cifara veci od 9 (tj. dvocifren), tada se njegove cifre jos
jednom saberu i tako se dobija odgovarajuca cifra (npr. za x{i} = 987,
9 + 8 = 17, pa ponovo sabiramo 1 + 7 = 8; slicno 8 + 7 = 15, pa ponovo
sabiramo 1 + 5 = 6; dakle, dobijamo broj x{i+1} = 86). Tajni broj polaznog
broja x ce biti prvi jednocifreni broj u formiranoj sekvenci. 
54) Napisati funkciju koja ispituje da li je ceo broj "nedodirljiv". Za
broj x kazemo da je nedodirljiv ako ne postoji broj y takav da je x 
jednak zbiru pravih delilaca broja y. Uputstvo: ako postoji takav broj
y, tada vazi y < x^2 (ovo vazi za x != 1, dok za x == 1, jasno je da 
nije nedodirljiv, jer je jednak zbiru pravih delilaca bilo kog prostog 
broja).
55) Napisati funkciju koja ispituje da li je dati ceo broj "mocan". Za
broj x kazemo da je mocan ako za svaki prost broj p, iz p|x => p^2|x.
Npr. takav je broj 72. Uputstvo: dovoljno je pokazati da je u 
razlaganju na proste cinioce: p1^i1 * p2^i2 * ... * pk^ik stepen svakog
prostog cinioca veci od 1. Ovo se moze uraditi izdvajanjem prostih 
cinilaca i brojanjem njihovih stepena.
56) Napisati funkciju koja pronalazi najvecu dekadnu cifru u datom broju x.
57) Napisati funkciju koja racuna zbir heksadekadnih cifara datog broja x.
58) Napisati funkciju koja odredjuje zbir razlicitih prostih delilaca 
datog broja x.
59) Napisati funkciju unsigned obrni(unsigned x) koja vraca broj koji nastaje
obrtanjem dekadnih cifara datog broja x (npr za x = 345 vraca 543).
60) Napisati funkciju koja zamenjuje susedne elemente u nizu celih brojeva
(tj. a[0] zamenjuje sa a[1], a[2] sa a[3] i sl. ukoliko je broj elemenata
niza neparan, tada poslednji element niza ne zamenjuje ni sa cim). 
61) Napisati funkciju koja sortira niz celih brojeva metodom izbora najmanjeg
elementa (u prvom prolazu kroz niz trazi se najmanji koji se potom postavlja
na pocetak niza, zatim se u sledecem prolazu trazi najmanji od preostalih 
i postavlja na sledece mesto, i td.). 
62) Napisati funkciju koja vrsi binarnu pretragu datog rastuceg niza.
63) Napisati funkciju koja ispituje da li je dati niz strogo rastuci (vraca
1 ako jeste, a 0 ako nije).
64) Napisati funkciju:

unsigned izracunaj(unsigned * a, int n, int b);

koja od datog niza celih brojeva duzine n ciji elementi predstavljaju cifre
u nekom brojevnom sistemu sa osnovom b izracunava i vraca broj cije su to
cifre. Npr. ako se niz duzine 3 sastoji od elemenata {8, 4, 2}, a osnova b
je 10, tada funkcija treba da vrati broj ciji je dekadni zapis 842.

65) Napisati funkciju koja odredjuje sve lokalne minimume datog celobrojnog
niza:

int lokalni_minimumi(int * a, int n, int * b);

Element a[i] (0 < i < n - 1) kazemo da je lokalni minumum ako vazi
a[i-1] > a[i] && a[i + 1] > a[i]. Funkcija treba da pronadje lokalne minimume
u nizu a duzine n i da njihove indekse u rastucem poretku smesti u niz b.
Funkcija broj lokalnih minimuma. Npr., za niz {3, 1, 6, 8, 5, 9} duzine 6,
funkcija treba da u niz b upise {1, 4} (indeksi lokalnih minimuma), i da 
vrati 2 (duzina formiranog niza). 

66) Napisati funkciju koja odredjuje dva najveca elementa niza.

67) Napisati funkciju koja odredjuje najduzu strogo rastucu sekvencu datog
celobrojnog niza. Funkcija treba da vrati indeks pocetka te sekvence kao i
duzinu sekvence.

68) Napisati funkciju koja odredjuje niz prvih n prostih brojeva:

void n_prostih(int n, int * p);

Prvih n prostih brojeva se upisuje u niz p. Npr, za n = 7, funkcija u niz
treba da upise elemente {2, 3, 5, 7, 11, 13, 17}.

69) Napisati funkciju koja za dati neozaceni ceo broj ispituje da li je niz
njegovih dekadnih cifara strogo rastuci. Npr, takav je broj 135, dok broj 
315 nije takav (januar 2014)

70) Napisati funkciju koja za dati neoznaceni ceo broj x ispituje da li je
potpuni stepen, tj. da li postoje brojevi m i k (k >= 2), takav da je
x = m^k ("m na k"). (februar 2014)

71) Napisati funkciju koja za dati neoznaceni ceo broj x odredjuje proizvod
svih njegovih razlicitih prostih delitelja (npr. za broj 120 = 2^3 * 3 * 5,
to je 2 * 3 * 5 = 30. (jun 2014)

