Ako to je s reprezentaciou necelych cisel v pocitacoch, ako sa ukladaju do pamate.
Na zaciatok by sa chcelo vidiet nieco o tom ako to vlastne s cislami v pocitaci vobec je.
Zacneme celymi cislami.
Majme C program:
int main () {
int a = 5;
printf("%i\n", a);
}
Tento program si vyhradi nejake miesto v pamati do ktoreho je schopny ulozit cislo typu
int
(int a = 5
). Typ int
zabera v pamati 4 bajty = 32 bitov (1 bajt = 8 bitov). To znamena, ze cislo 5 ktore don ulozime zaberie 32 bitov a v dvojkovej sustave sa zapise ako:5 = 00000000 00000000 00000000 00000101
(Obycajny prevod do dvojkovej sustavy).
Takto mozno dosiahnut celkovo 232 = 4,294,967,296 roznych cisel. Typ int
moze obsahovat aj zapornu hodnotu, a to pocitanim z opacnej strany - odpocitavanim z najvyssej hodnoty 232, napriklad cislo -1 bude reprezentovane ako 232-1:
+3 = 00000000 00000000 00000000 00000011
+2 = 00000000 00000000 00000000 00000010
+1 = 00000000 00000000 00000000 00000001
+0 = 00000000 00000000 00000000 00000000
-1 = 11111111 11111111 11111111 11111111
-2 = 11111111 11111111 11111111 11111110
To znamena, ze
int
moze obsahovat hodnoty od -231 do 231-1 (od -2147483648 do 2147483647), co je dohromady spominanych 232 cisel (aj s nulou).
Tiez celosicelne typy short
a char
su na tom takto:
short - (2 bajty = 16 bitov)
2^16 = 65,536 roznych hodnot od -32768 do 32767,
char - (1 bajt = 8 bitov)
2^8 = 256 roznych hodnot od -128 do 127.
Popripade este je 8 bajtov = 64 bitov dlha hodnota pouzivana pre velke cisla (v cecku sa nazyva
long long int
).
Ak dopredu vieme, ze nebudeme pouzivat zaporne cisla, premennej mozme pridelit predponu unsigned
(unsigned int
, unsigned short
, ...).
Potom ma napriklad typ unsigned int
mozne hodnoty od 0 do 232-1 (od 0 do 4294967295).
Suhrn:
8B = long long int ( = long long )
4B = long int ( = long = int )
2B = short int ( = short )
1B = char
char od -128 do 127
short od -32768 do 32767
int od -2147483648 do 2147483647
long long od -9223372036854775808 do 9223372036854775807
unsigned char od 0 do 255
unsigned short od 0 do 65535
unsigned int od 0 do 4294967295
unsigned long long od 0 do 18446744073709551615
Desatinne cisla
V pripade desatinnych cisel je to inak. Kedze nevieme, kde v cisle sa bude nachadzat desatinna ciarka (a zapisat ju niekde pevne, napriklad ze ma byt presne v polovici cisla nie je vyhodne, pretoze na vacsie cisla by sme potrebovali vela pamate), vyriesilo sa to inac.
Najviac je pouzivany Medzinarodny standard pre binarnu desatinnu aritmetiku IEEE 754.
V tomto clanku opisem IEEE 754 single precision. V cecku sa takemuto typu nadava float
.
Kazde cislo sa sklada z troch casti: znamienko, exponent a mantissa.
Pre ulozenie do 32 bitoveho priestoru (single precision) je zlozenie desatinneho cisla taketo:
S EEEEEEEE MMMMMMMMMMMMMMMMMMMMMMM
S - sign (znamienko) 1 bit
E - exponent 8 bitov
M - mantissa 23 bitov
To znamena ze prva cast urcuje znamienko:
ak S = 0, cislo je kladne,
sk S = 1, cislo je zaporne.
Druha cast je umocnenie cisla 2 na exponent (od ktoreho sa odpocita hodnota 127).
Tretia cast mantissa je vlastne zvysny podiel ktorym treba nasobit aby sme dosiahli nase cislo. POZOR: Mantissa obsahuje skrytu jednotku na zaciatku, ktora tam je vzdy a preto sa nezapisuje (1.M). Napriklad ak je mantissa zapisana ako:
00110011001100110011001
v skutocnosti to je
1.00110011001100110011001
Preco sa od exponentu odcitava hodnota 127? Je to preto, aby sme mohli dosiahnut presnost za desatinnou ciarkou (teda aj zaporne hodnoty, ak E=3, v skutocnosti je exponent 3-127 = -124).
Priklad premeny 0.75:
Chceme premenit cislo 0.7510 do standardu IEEE 754 signle precision.
0.7510 = 0.112 (premenene do dvojkovej sustavy)
0.7510 = 1.1 * 2-1 (normalizovane dvojkove cislo)
Cislo sme normalizovali preto, aby sme na zaciatku mali pred desatinnou ciarkou jednotku, ktora je skryta.
Cislo je kladne: S = 0.
Exponent pri dvojke je -1, E je vzdy zvascene o 127:
E = -1 + 127 = 126 = 01111110.
Desatinna cast manissy:
M = 10000000000000000000000 (23 bitov)
Cislo 0.75 sa vo formate IEEE 754 single precision reprezentuje ako:
0 01111110 10000000000000000000000 (32 bitov)
Priklad premeny -2345.125:
-2345.12510 = -100100101001.0012
-2345.12510 = -1.00100101001001 * 211
(normalizovane)
Cislo je zaporne: S = 1.
Exponent pri dvojke je 11, E je zvacene o 127:
E = 11 + 127 = 138 = 10001010.
M = 00100101001001000000000 (23 bitov)
Cislo -2345.125 sa vo formate IEEE 754 single precision reprezentuje ako:
1 10001010 00100101001001000000000 (32 bitov)
Specialne pripady
Exponent E moze byt v rozmedzi od 0 do 255. Odcitany moze byt v rozmedzi -127 do 128. V skutocnosti vsak iba od -126 do 127, pretoze hodnoty -127 a 128 (E=00000000 a E=11111111) sa pouzivaju na specialne pripady cisel:
Ak E = 0 a S = 0
hodnota cisla = 0
Ak E = 0 a S = 1
nenormalizovane cislo, (vysledk tzv. underflowu pri nasobeni)
Ak E = 255 a S = 0
infinity (nekonecno). Napriklad pri deleni nulou.
Ak E = 255 a S = 1
NaN (Not A Number). Napriklad pri deleni nuly nulou.
Pre pridávanie komentárov sa musíte prihlásiť.