Liczby stało- i zmiennoprzecinkowe

Transkrypt

Liczby stało- i zmiennoprzecinkowe
Adam Korzeniewski
[email protected]
p. 732 - Katedra Systemów Multimedialnych
Sygnały dyskretne są z reguły przetwarzane w
komputerach (zwykłych lub wyspecjalizowanych,
takich jak procesory sygnałowe).
 Komputery wykonują działania na liczbach
zapisanych za pomocą skończonej liczby bitów (na
ogół jest to 16, 24, 32 lub 64 bity).
 Dlatego sygnały dyskretne są kwantowane przed
wprowadzeniem do pamięci komputera.

Najlepiej, gdy przetwornik analogowo-cyfrowy ma
taką samą liczbę bitów jak komputer, w przeciwnym
razie moce szumów kwantowania przetwornika i
komputera zsumują się.
 Podobnie jak wartości próbek sygnału, zostaną
skwantowane inne dane wykorzystywane przy
cyfrowym przetwarzaniu sygnałów, jak np.
współczynniki filtrów cyfrowych.

Skwantowana wartość liczbowa może być
zakodowana na wiele różnych sposobów.
 Podstawowe metody kodowania dwójkowego
zestawiono w tabeli na kolejnym slajdzie, przy czym
naturalny kod dwójkowy służy do kodowania liczb
dziesiętnych bez znaku, a pozostałe kody pozwalają
kodować liczby dziesiętne ze znakiem.

Liczba
Naturalny
dziesiękod dwójkowy
tna
bez znaku L2   b2 b1 b0 2  
L10
-4
-3
-2
-1
0
1
2
3
4
5
6
7
b2 2 2  b1 2 1  b0
000
001
010
011
100
101
110
111
Kod
znak-moduł
Kod z uzupełnieniem do 1
L ZM  
 b2b1b0ZM  

  1 b1 2  b0
b2
1
111
110
101
000 lub 100
001
010
011

Kod z uzupełnieniem do 2
LU 1 
LU 2  
 b2b1b0U 1 
 b2b1b0U 2  
 b2  22  1 


 b2  22 
Liczba
dziesiętna ze
zna-kiem
1
 b1 2  b0
1
 b1 2  b0
LZ 10
100
101
110
000 lub 100
001
010
011
100
101
110
111
000
001
010
011
-4
-3
-2
-1
0
1
2
3
Najprostszym kodem jest naturalny kod dwójkowy
(w tym kodzie zapisuje się liczby naturalne, kod nie
uwzględnia znaku liczby). W tym kodzie operacja
dodawania pojedynczych bitów daje następujące wyniki:
0+0=0, 0+1=1, 1+1=10 (tutaj występuje jedynka
przeniesienia). Stąd wynika zasada dodawania liczb
z większą liczbą bitów. Na przykład
1 1 1
dodawaniu dziesiętnemu odpowiada
pokazane obok dodawanie dwójkowe 1 0 1 0 1 1
(na samej górze zapisano jedynki 
1 0 1 1 1 0
przeniesienia)

1 0 1 1 0 0 1
Z kolei wyniki mnożenia pojedynczych bitów są
następujące: 0*0=0, 0*1=0, 1*1=1, a dla liczb z większą
liczbą bitów mamy przykład (odpowiednik mnożenia
dziesiętnego ). Bardzo łatwo można
1 1 0
wykonać mnożenie razy 2, gdyż

1 0 1
wystarczy przesunąć wszystkie bity        
o jedną pozycję w lewo. Podobnie
1 1 0
łatwe jest dzielenie przez 2, gdyż
0 0 0
wystarczy przesunąć wszystkie bity 1 1 0

o jedną pozycję w prawo.
1 1 1 1 0
Są znane reguły wykonywania działań na liczbach
zapisanych w innych kodach niż kod naturalny.
Popularnym kodem jest kod z uzupełnieniem do 2 (kod
U2). Należy on do kodów pozwalających wykonywać
operacje na liczbach z uwzględnieniem ich znaku.
Pierwszy bit (MSB) jest bitem znaku liczby (0 – liczba
dodatnia, 1 – liczba ujemna).
Bardziej niż działaniami na liczbach całkowitych jesteśmy
zainteresowani działaniami na liczbach ułamkowych. W
tym przypadku jest stosowana postać stałoprzecinkowa
lub postać zmiennoprzecinkowa liczby.
W postaci stałoprzecinkowej do zapisu liczby o postaci
 M .F przeznacza się jeden bit s=1 na zapis znaku liczby,
m bitów na zapis części całkowitej M i f bitów na zapis
części ułamkowej liczby F, czyli długość słowa
maszynowego to w  s  m  f
a)
w=1+m+f – długość słowa maszynowego
MSB
bw1 bw 2 bw3
L
L
b2
b1
LSB
b0
L 20
21 L
m – część całkowita liczby Kropka f – część ułamkowa liczby
binarna
Oś
Precyzja  2  f
m
2
2 m  2  f liczbowa
0
s - bit
znaku
Przekrocze nie
ujemne
Liczby ujemne
b)
Przekroczenie
dodatnie
Liczby dodatnie
w=1+e+f – długość słowa maszynowego
MSB
L
bw1 bw 2
L
L
s - bit
znaku
21
e – wykładnik


 2  2 f 22
Przekroczenie
ujemne
e
 bias
Liczby
ujemne
20
2 1
b2
2 2 L
b1
LSB
b0
f – część ułamkowa
 2  f 1bias 2  f 1bias
0
Niedobór Niedobór
ujemny dodatni
2  2 2
f
Liczby
dodatnie
2 e bias
Oś
liczbowa
Przekroczenie
dodatnie
Przykładowo w kodzie z uzupełnieniem do dwóch (U2) zapis
liczb jest następujący
10101 U 2 
010101 U 2 
  1  2 4  0  2 3  1  2 2  0  21  1  2 0  11
  0  2 5  2 4  2 2  2 0  21
11.111U 2 
  21  2 0  2 1  2 2  2 3  0.125
01.101 U 2 
  0  21  2 0  2 1  2 3  1.625
W tej postaci można zapisać liczby w zakresie od  2 do
2 m  2  f z precyzją co 2  f . Jak widać, nie jest możliwe
dokładne zapisanie liczby niewymiernej, a i wśród liczb
wymiernych dokładną reprezentację ma tylko ich skończona
ilość (te, które są podzielne przez 2  f ).
m
W postaci zmiennoprzecinkowej do zapisu liczby o postaci  1.F  2  E przeznacza
się jeden bit s=1 na zapis znaku liczby, e bitów na zapis wykładnika E i f bitów na
zapis części ułamkowej F (nazywanej też mantysą), czyli długość słowa
maszynowego, to w = s + e + f.
W standardzie IEEE 754-1985 przy 32-bitowym zapisie liczby rozdział bitów jest
następujący w = 1 + 8 + 23, a przy zapisie 64-bitowym jest to w = 1 + 11 + 52.
Nie przeznacza się bitu na zapis znaku wykładnika, ale przesuwa się wartości
wykładnika w dół o wartość bias  2e1  1 . Na przykład przy e=8, liczby od 0 do 255
po przesunięciu o 2 e1  1  127 dają wartości wykładnika zmieniające się w
zakresie od –127 do 128. I tak zapisowi binarnemu
1|00100101|11000101000000000000000
odpowiada liczba dziesiętna
 11  1  2 1  2 2  2 6  2 8  2 2 2 2 127  1.76953125  2 92  3.5735  10 28
0
2
5
W standardzie IEEE 754-1985 rezygnuje się z wartości wykładnika –127 (E – same
zera) i 128 (E – same jedynki), aby umożliwić zapisanie wartości zero i
nieskończoność. Stworzono też możliwość zapisania tzw. wartości
zdenormalizowanych i NaN (Not a Number), tak jak to pokazano w poniższej
tabeli. W tabeli tej zamieszczono tylko wartości dodatnie (bit znaku 0), ale każda
z nich ma swój odpowiednik ujemny (bit znaku 1). Na przykład zero ma dwie
Ułamek (F)
Wartości
Dla
bity Dla
bity
reprezentacje: +0 i –0. Wykładnik (E)
w  32
w  64
00...00
00...00
00...00
00...01
do
11...11
+0
Zdenormalizowane
1bias
0.F  2
00...01
do
11...10
00...00
do
11...11
1.F  2 E bias
11...11
00...00
+infinity
11...11
11…11
00...01
do
01...11
10…00
do
11…11
Normalizowane
2149 do
1  223 2126
2126do
1  2 2
52
1022
21022do
2  2 2 2  2 2
23
Signalling
Not a Number
SNaN
Quiet
Not a Number
QNaN
21074do
127
52
1023

Procesory stałoprzecinkowe (fixed point):
 operują na liczbach stałoprzecinkowych
(„całkowitych”), np. 16536
 nie „rozumieją” liczb ułamkowych, np. 0,56

Procesory zmiennoprzecinkowe:
 potrafią działać na liczbach ułamkowych
 specjalny procesor i zestaw instrukcji
 wolniejsze, droższe, większe zużycie energii


Procesor TMS320C5535 – używany
w projekcie ZPS – jest stałoprzecinkowy.
Typy liczbowe:
 16-bitowy (int, short)
 32-bitowy (long) + 40-bitowy (long long)

Każdy typ n-bitowy występuje w wersji:
 ze znakiem (signed, domyślny): -2(n-1) do 2(n-1)-1
 bez znaku (unsigned): 0 do 2n-1




„Czy to znaczy, że nie da się zapisać liczb
ułamkowych, np. 0,53?”
16 bitów: mamy do dyspozycji liczby
od -215 do 215-1, czyli od -32768 do 32767
Załóżmy, że zapisujemy liczby z zakr. [-1, 1)
Przeskalujmy:
 1
 -1
 0,53



 1 * 32768  = 32767
 -1 * 32768  = -32768
 0,53 * 32768  = 17367





Znaczenie 16 bitów:
znak, 2-1, 2-2, 2-3, 2-4, …, 2-14, 2-15
Taki zapis nazywa się Q15: 1 bit znaku,
15 bitów liczby ułamkowej
Rozdzielczość: 2-15 = 0,0000305
Nie da się dokładnie zapisać liczby 1.
UWAGA: ta konwersja zachodzi po stronie
programisty. Procesor nadal widzi liczbę
17367, nie 0,53!
W formacie tym jeden bit przeznacza się na zapis znaku, zero bitów
na zapis części całkowitej i 15 bitów na część ułamkową w = s + m + f
= 1 + 0 + 15 = 16.
Na przykład liczba zapisana w kodzie U2
1|011110100000000
ma następującą wartość w zapisie dziesiętnym
 1  22  23  24  25  27  0.5234375

Sprawdźmy czy to działa: 0,53+0,26
 0.53 * 32768 = 17367
 0.26 * 32768 = 8519
 17367 + 8519 = 25886

Powrót do liczby dziesiętnej:
 25886 / 32768 = 0,789978  0.79



A co jeśli mamy np. liczby z zakresu [-2; 2)?
Skalujemy tak samo: 2  32768,
czyli 1  32768 / 2 = 16384 (zapis Q14 lub Q1.14)
Obliczamy 0,58 – 1,34:
 0,58 * 16384 = 9502
 1,34 * 16384 = 21954
 9502 – 21954 = -12452
 -12452 / 16384  -0,76

Ogólnie: zapis liczb z przedziału [-2n; 2n),
czyli zapis Qm.n:
 Konwersja z dziesiętnej na Qm.n:
q =  d * 2n 
 Konwersja z Qm.n na dziesiętną:
d = q / 2n



Mnożenie dwóch liczb Q15 przez siebie daje
w wyniku liczbę Q(15+15), czyli Q30.
Do zapisania wyniku potrzebujemy 32 bity.
Mnożenie przez potęgi dwójki 2n jest bardzo
proste: wykonujemy przesunięcie bitowe
o n miejsc w lewo (<< n), np.:
 x * 16 = x * 24 = x << 4
 np. 5 * 16 = 000001012 << 4 = 010100002 = 80

Przykład mnożenia: 0,7 * 0,8
 0,7 * 32768 = 22937
 0,8 * 32768 = 26214
 22937 * 26214 = 601 270 518 (32 bity!)
 to jest liczba Q30, więc przeliczenie na dziesiętną:
601270518 / 230 = 0,55976  0,56




Wynik mnożenia liczb Q15 to liczba Q30.
Co zrobić jeżeli chcemy mieć wynik Q15?
Musimy „obciąć” 15 najmłodzych bitów części
ułamkowej.
Robimy to przesuwając bity o 15 miejsc
w prawo (>> 15).
 601270518 >> 15 = 18349 (Q15)
 18349 / 32768  0,56 (dziesiętna)

Odpowiada to dzieleniu przez 215





Należy tego unikać, jeśli to tylko możliwe
- dzielenie jest baaaaaardzo wolne.
Szybkie dzielenie tylko przez 2n (>> n).
Można dzielić a/b (Q15) jeżeli a < b.
Dzielenie liczb Q15 da wynik Q(15-15) = Q0 (!)
Musimy zamienić licznik a na Q30, wtedy
dostaniemy wynik Q(30-15) = Q15.
 0,3 / 0,5  (0,3 * 230) / (0,5 * 215) =
= 322122547 / 16384 = 19660  0,6 (dziesiętna)




Format Qm.n pozwala kodować liczby
ułamkowe jako stałoprzecinkowe.
Konwersja na Q i z Q jest robiona przez
programistę.
Procesor nadal wykonuje operacje na
liczbach stałoprzecinkowych.
Działania podatne na wystąpienie
przepełnienia zakresu (overflow) oraz
niedopełnienia (underflow – wyzerowanie).



Niezależnie od przyjętej postaci zapisu liczby, komputer jest w
stanie zapisywać dokładnie liczby tylko ze skończonego zbioru
skwantowanych liczb wymiernych.
Komputery „nie potrafią” zapisać dokładnie liczby niewymiernej
(np. w komputerze 32-bitowym liczba pi, to 355/113 z
dokładnością 10-6), ani liczby wymiernej, która nie należy do tego
zbioru. Takie liczby są zaokrąglane do najbliższej liczby mającej
swoją reprezentację w komputerze.
To spowoduje, że np. współczynniki zaprojektowanego filtru
cyfrowego nigdy nie będą dokładnie reprezentowane w
komputerze i w konsekwencji charakterystyki zrealizowanego
filtru będą różniły się od charakterystyk idealnych.



Analiza błędów zaokrągleń jest trudna, gdyż błędy te zależą
dodatkowo od algorytmu, według którego komputer wykonuje
obliczenia.
Nawet w najprostszych algorytmach przy pewnych wartościach
parametrów obserwuje się efekt oscylacji błędu ze stałą
amplitudą lub efekt kumulacji błędu i jego narastanie do
nieskończoności.
Na przykład przy całkowaniu numerycznym równań
różniczkowych niedopuszczalne jest stosowanie algorytmów
niestabilnych numerycznie, „wzmacniających” błędy zaokrągleń;
powodujących, że bardzo szybko zakumulowane błędy stają się
większe od poszukiwanego rozwiązania.
Innym źródłem błędów jest przekroczenie dopuszczalnego zakresu
zmienności liczby (przekroczenie zakresu dynamicznego).
 Przekroczenie takie może zajść przy dodawaniu, a zwłaszcza mnożeniu
liczb. Przy mnożeniu dwóch liczb iloczyn może wymagać do zapisu
dwukrotnie większej liczby bitów niż każdy z czynników. Dlatego w
komputerach akumulatory, do których wpisuje się wyniki działań , są
dłuższe niż rejestry, z których pobiera się liczby do obliczeń .
 Jeżeli do akumulatora zostanie wpisana wartość końcowa obliczeń, to
będzie ona znana z dużą dokładnością (podwójną precyzją, gdy
akumulator jest dwukrotnie dłuższy od rejestrów). Jeśli jednak jest to
wynik pośredni obliczeń i przekracza długość rejestru, to musi być
obcięty przed umieszczeniem w rejestrze i zachodzi błąd
przekroczenia.

Rejestr A
Akumulator
Rejestr B
Np. 8 bitów
Np. 8 bitów
Np. 16 bitów
Hardwarowy
mnożnik
Jednostka
dodająca
ALU – jednostka
arytmetycznologiczna
Szyny danych
i rozkazów





Z powodu błędów zaokrągleń i przekroczeń dokładność obliczeń
wykonywanych na tym samym komputerze będzie zależała od
kolejności wykonania przemiennych operacji.
Także dwa różnego typu komputery o tej samej długości słowa
maszynowego będą dawały nieco różniące się wyniki nawet przy tej
samej kolejności wykonywania operacji.
W większości przypadków komputer czy procesor sygnałowy z 32
bitowym zapisem zmiennoprzecinkowym liczby zapewni dostateczną
dokładność obliczeń.
W wielu typach komputerów istnieje możliwość poprawienia
dokładności obliczeń (za cenę zwiększenia czasu obliczeń) poprzez
przejście na zapis liczb z podwójną precyzją 2 * 32 = 64 bity.
W przypadku procesorów sygnałowych procesory
zmiennoprzecinkowe zapewniają większą precyzję i zakres
dynamiczny są jednak mniej ekonomiczne niż procesory
stałoprzecinkowe, gdyż mają większy pobór mocy, większe rozmiary,
wyższą cenę.


Wykonując obliczenia komputerowo zawsze warto zadbać o to,
aby już począwszy od danych wejściowych posługiwać się w
obliczeniach wielkościami unormowanymi, przyjmującymi
wartości zbliżone do jedności.
W przeciwnym razie od samego początku komputer będzie
wykonywał obliczenia na wartościach liczbowych bardzo
różniących się modułami i błędy obliczeń będą większe.

Podobne dokumenty