Search
 
 
  Engleski
 
 
 
Open in this window (click to change)
Forum@DeGiorgi: Početna
Forum za podršku nastavi na PMF-MO
Login Registracija FAQ Smajlići Članstvo Pretražnik Forum@DeGiorgi: Početna

Procitati prije programiranja s bazama (brojevnim sustavima) (objasnjenje gradiva)
WWW:

Moja sarma
 
Započnite novu temu   Odgovorite na temu   printer-friendly view    Forum@DeGiorgi: Početna -> Kolegiji 1. godine, preddiplomski studij Matematika -> Programiranje 1 i 2
Prethodna tema :: Sljedeća tema  
Autor/ica Poruka
vsego
Site Admin
Site Admin


Pridružen/a: 06. 10. 2002. (22:07:09)
Postovi: (355F)16
Spol: zombi
Sarma = la pohva - posuda
854 = 1068 - 214
Lokacija: /sbin/init

PostPostano: 15:40 pon, 26. 11. 2012    Naslov: Procitati prije programiranja s bazama (brojevnim sustavima) Citirajte i odgovorite

[size=7]Ovaj post je nastao jer mi je konacno dosadilo svake godine pisati isto. Sad mogu samo dati link.[/size] 8)

[b]Poanta:[/b] "Broj" i "zapis broja" su dva vrlo razlicita pojma.
Broj se moze [color=blue][i]zapisati u nekoj bazi[/i][/color], pri cemu se sam broj ne mijenja, nego samo njegov zapis.
Broj se [u]ne moze[/u] [color=red][i]pretvoriti iz jedne baze u drugu[/i][/color], jer promjena broja znaci da to vise nije isti broj.

Svi kojima ova poanta nije kristalno jasna i/ili ne razumiju zasto je vazna, nastavite citati. Ostali, svejedno procitajte. :P

Ako napisete program koji sadrzi ovako nesto
[code:1]broj_n_u_bazi_b = 0;
potencija_baze = 1;
while (n > 0) {
broj_n_u_bazi_b += potencija_baze * (n % b);
potencija_baze *= 10;
n /= b;
}[/code:1]
vjerojatno cete biti uvjereni da je rijec o "pretvaranju broja u bazu b" ili tako necemu.

No, broj se ne moze "pretvoriti u bazu", nego samo zapisati u njoj. Dakle, da ste ispisivali [tt]n % b[/tt] u gornjoj petlji, zaista biste ispisali znamenke broja [tt]n[/tt] kad ga se zapise u bazi [tt]b[/tt] (redoslijed ispisa je s desna nalijevo, ali to sada nije bitno).

Ono sto vas program radi je da neki broj zamijeni s brojem koji zapisan dekadski izgleda kao ovaj prvi kad se zapise u bazi [tt]b[/tt]. Na primjer, [tex]n = 6[/tex] ce zamijeniti sa [tex]110[/tex]. To mozda izgleda kao da ima smisla jer je [tex](6)_{10} = (110)_2[/tex], ali ne mijenja cinjenicu da je jedan broj [b]sest[/b], a drugi je [b]sto i deset[/b] i oni nemaju veze jedan s drugim!

U nastavku programa cete sa znamenkama broja raditi tako da broj dijelite s 10, no postavlja se pitanje cemu ta gimnastika? Zasto jednostavno ne dijelite stalno s [tt]b[/tt] i zaboravite "pretvaranje"?

Ne bi ovo bilo tako lose, da ne uzrokuje stvarno ozbiljne probleme.

[b]Problem 1:[/b]

Recimo da zelimo nesto raditi s brojem [tex]4096 = 2^{12} = (1000000000000)_2[/tex], sto binarno zapisano ima jednu jedinicu i 12 nula. Pokusate li to "pretvoriti" kako je gore prikazano, dobit cete broj koji, zapisan dekadski, jednako [b]izgleda[/b] kao 4096 zapisan binarno. Dakle, dobit cemo broj koji u dekadskom zapisu ima jednu jedinicu i nakon nje 12 nula.

Problem lezi u neprikazivosti tog broja u standardnoj aritmetici racunala. Naime,
[tex]1000000000000 = (1110100011010100101001010001000000000000)_2[/tex],
sto znaci da za prikaz tog broja treba 40 bitova, a u [tt]int[/tt] stane samo 31 (u [tt]unsigned[/tt] stanu 32 bita) i program se raspadne.

Naravno, mozemo koristiti [tt]long[/tt] ili cak tipove mimo standarda, poput [tt]long long[/tt], ali to samo znaci da cemo uhvatiti sitno brojeva vise. Recimo, broj [tex]1048576 = 2^{20}[/tex] u binarnom zapisu ima jednu jedinicu i 20 nula. Gornjim "pretvaranjem" dobijemo broj koji za zapis trazi 67 bitova. Dakle, nas pocetni broj stane u obicni [tt]int[/tt], a "pretvoreni" ne stane niti u dvostruko vise memorije.

Koristenjem tipa [tt]double[/tt] radimo jos vece zlo, jer se gube znamenke u algoritmu koji bi morao biti cisto cjelobrojni, sto znaci da bi morao imati pouzdano tocan rezultat i ne bi smio pogubiti niti jednu jedinu znamenku.

[b]Problem 2:[/b]

Sto se dogadja u bazama vecim od 10?

Recimo, neka je baza [tt]b = 16[/tt]. "Pretvorimo" li brojeve 11 i 17, dobit cemo identican rezultat: 11. To znaci da negdje dolazi do neke ozbiljne greske, jer ne mogu dva razlicita broja imati jednak zapis. Naravno, stvar je u tome da 11 treba postati B, no takva dekadska znamenka ne postoji, pa "pretvaranje" ispada potpuno pogresno.

[b]Zakljucak[/b]

Nikad, ali stvarno [b][u]NIKAD[/u][/b], nemojte "pretvarati" broj iz jedne baze u drugu. Ako se trazi nesto sa zapisom broja u bazi, dijelite broj s bazom i racunajte znamenke. Ako treba, i nekoliko puta u programu, ali nemojte "pretvarati" samo zato da bi u vecem dijelu programa imali dijeljenje s 10 umjesto s [tt]b[/tt], jer je to jednostavno pogresno.

Ako na nekom kolokviju/ispitu negdje napravite "pretvaranje", ispitivac ima puno pravo samo prekriziti rjesenje kao krivo, bez da uopce gleda sto pise iza tog "pretvaranja".
Ovaj post je nastao jer mi je konacno dosadilo svake godine pisati isto. Sad mogu samo dati link. Cool

Poanta: "Broj" i "zapis broja" su dva vrlo razlicita pojma.
Broj se moze zapisati u nekoj bazi, pri cemu se sam broj ne mijenja, nego samo njegov zapis.
Broj se ne moze pretvoriti iz jedne baze u drugu, jer promjena broja znaci da to vise nije isti broj.

Svi kojima ova poanta nije kristalno jasna i/ili ne razumiju zasto je vazna, nastavite citati. Ostali, svejedno procitajte. Razz

Ako napisete program koji sadrzi ovako nesto
Kod:
broj_n_u_bazi_b = 0;
potencija_baze = 1;
while (n > 0) {
  broj_n_u_bazi_b += potencija_baze * (n % b);
  potencija_baze *= 10;
  n /= b;
}

vjerojatno cete biti uvjereni da je rijec o "pretvaranju broja u bazu b" ili tako necemu.

No, broj se ne moze "pretvoriti u bazu", nego samo zapisati u njoj. Dakle, da ste ispisivali n % b u gornjoj petlji, zaista biste ispisali znamenke broja n kad ga se zapise u bazi b (redoslijed ispisa je s desna nalijevo, ali to sada nije bitno).

Ono sto vas program radi je da neki broj zamijeni s brojem koji zapisan dekadski izgleda kao ovaj prvi kad se zapise u bazi b. Na primjer, [tex]n = 6[/tex] ce zamijeniti sa [tex]110[/tex]. To mozda izgleda kao da ima smisla jer je [tex](6)_{10} = (110)_2[/tex], ali ne mijenja cinjenicu da je jedan broj sest, a drugi je sto i deset i oni nemaju veze jedan s drugim!

U nastavku programa cete sa znamenkama broja raditi tako da broj dijelite s 10, no postavlja se pitanje cemu ta gimnastika? Zasto jednostavno ne dijelite stalno s b i zaboravite "pretvaranje"?

Ne bi ovo bilo tako lose, da ne uzrokuje stvarno ozbiljne probleme.

Problem 1:

Recimo da zelimo nesto raditi s brojem [tex]4096 = 2^{12} = (1000000000000)_2[/tex], sto binarno zapisano ima jednu jedinicu i 12 nula. Pokusate li to "pretvoriti" kako je gore prikazano, dobit cete broj koji, zapisan dekadski, jednako izgleda kao 4096 zapisan binarno. Dakle, dobit cemo broj koji u dekadskom zapisu ima jednu jedinicu i nakon nje 12 nula.

Problem lezi u neprikazivosti tog broja u standardnoj aritmetici racunala. Naime,
[tex]1000000000000 = (1110100011010100101001010001000000000000)_2[/tex],
sto znaci da za prikaz tog broja treba 40 bitova, a u int stane samo 31 (u unsigned stanu 32 bita) i program se raspadne.

Naravno, mozemo koristiti long ili cak tipove mimo standarda, poput long long, ali to samo znaci da cemo uhvatiti sitno brojeva vise. Recimo, broj [tex]1048576 = 2^{20}[/tex] u binarnom zapisu ima jednu jedinicu i 20 nula. Gornjim "pretvaranjem" dobijemo broj koji za zapis trazi 67 bitova. Dakle, nas pocetni broj stane u obicni int, a "pretvoreni" ne stane niti u dvostruko vise memorije.

Koristenjem tipa double radimo jos vece zlo, jer se gube znamenke u algoritmu koji bi morao biti cisto cjelobrojni, sto znaci da bi morao imati pouzdano tocan rezultat i ne bi smio pogubiti niti jednu jedinu znamenku.

Problem 2:

Sto se dogadja u bazama vecim od 10?

Recimo, neka je baza b = 16. "Pretvorimo" li brojeve 11 i 17, dobit cemo identican rezultat: 11. To znaci da negdje dolazi do neke ozbiljne greske, jer ne mogu dva razlicita broja imati jednak zapis. Naravno, stvar je u tome da 11 treba postati B, no takva dekadska znamenka ne postoji, pa "pretvaranje" ispada potpuno pogresno.

Zakljucak

Nikad, ali stvarno NIKAD, nemojte "pretvarati" broj iz jedne baze u drugu. Ako se trazi nesto sa zapisom broja u bazi, dijelite broj s bazom i racunajte znamenke. Ako treba, i nekoliko puta u programu, ali nemojte "pretvarati" samo zato da bi u vecem dijelu programa imali dijeljenje s 10 umjesto s b, jer je to jednostavno pogresno.

Ako na nekom kolokviju/ispitu negdje napravite "pretvaranje", ispitivac ima puno pravo samo prekriziti rjesenje kao krivo, bez da uopce gleda sto pise iza tog "pretvaranja".



_________________
U pravilu ignoriram pitanja u krivim topicima i kodove koji nisu u [code]...[/code] blokovima.
Takodjer, OBJASNITE sto vas muci! "Sto mi je krivo?", bez opisa u cemu je problem, rijetko ce zadobiti moju paznju.
Drzim prodike
[Vrh]
Korisnički profil Pošaljite privatnu poruku
Prethodni postovi:   
Započnite novu temu   Odgovorite na temu   printer-friendly view    Forum@DeGiorgi: Početna -> Kolegiji 1. godine, preddiplomski studij Matematika -> Programiranje 1 i 2 Vremenska zona: GMT + 01:00.
Stranica 1 / 1.

 
Forum(o)Bir:  
Ne možete otvarati nove teme.
Ne možete odgovarati na postove.
Ne možete uređivati Vaše postove.
Ne možete izbrisati Vaše postove.
Ne možete glasovati u anketama.
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2002 phpBB Group
Theme created by Vjacheslav Trushkin
HR (Cro) by Ančica Sečan