Standard IEEE 754


Podrozdziały Tematy pokrewne
 

Aby ujednolicić wyniki obliczeń numerycznych wykonywanych na różnych platformach sprzętowych, wprowadzono ściśle określony standard zapisu zmiennoprzecinkowego IEEE 754. W następnym rozdziale przedstawiamy wywiad z profesorem Williamem Kahanem - jednym z twórców tego standardu. Jak na warunki szkoły średniej standard IEEE 754 jest dosyć skomplikowany, ponieważ nie został on opracowany do nauki lecz do praktycznych zastosowań inżynierskich i naukowych. Jednakże nie widzę powodów, aby zdolny uczeń liceum nie mógł sobie go przyswoić - wiedza ta zaowocuje na studiach wyższych oraz wpłynie na zrozumienie zalet i ograniczeń obliczeń komputerowych.

 

Definicja formatu zmiennoprzecinkowego IEEE 754

Standard IEEE 754 definiuje dwa rodzaje liczb zmiennoprzecinkowych: 32-bitowe (pojedynczej precyzji - ang. single precision) oraz 64-bitowe (podwójnej precyzji - ang. double precision). Kod binarny liczby zmiennoprzecinkowej podzielony jest na trzy pola zawierające komponenty zapisu zmiennoprzecinkowego:

 

Format zapisu zmiennoprzecinkowego IEEE 754
32 bity - pojedyncza precyzja (1 bit)   b31 (8 bitów)   b30 ... b23 (BIAS=127) (23 bity)   ,b22 ... b0 (U1)
64 bity - podwójna precyzja (1 bit)   b63 (11 bitów)   b62 ... b52 (BIAS=1023) (52 bity)   ,b51 ... b0 (U1)
Opis pół bitowych bit znaku bity kodu cechy bity ułamkowe mantysy

 

Bit znaku

Pierwszy bit w zapisie liczby zwany jest bitem znaku. Stan 0 oznacza liczbę dodatnią, stan 1 liczbę ujemną. Aby zatem zmienić znak liczby zmiennoprzecinkowej na przeciwny, wystarczy dokonać negacji tego bitu.

 

Bity kodu cechy

Liczby zmiennoprzecinkowe IEEE 754 zapisują cechę w kodzie z nadmiarem.

W pojedynczej precyzji cecha posiada 8 bitów, a nadmiar wynosi 127. Zatem w polu cechy można zapisać wartości od -127 (wszystkie bity b30...b23 wyzerowane) do 128 (wszystkie bity b30...b23 ustawione na 1).

W podwójnej precyzji cecha zbudowana jest z 11 bitów, nadmiar wynosi 1023. Najmniejszą wartością będzie -1023 (bity b62...b52 ustawione na 0) , a największą 1024 (bity b62...b52 ustawione na 1). Wzrost ilości bitów cech liczb zmiennoprzecinkowych wpływa a ich zakres.

 

UWAGA:

Cechy zbudowane z samych zer i z samych jedynek pełnią w standardzie IEEE 754 specjalne funkcje nie związane z ich normalnym znaczeniem. Opisujemy to szczegółowo w dalszej części artykułu.

 

Bity ułamkowe mantysy

W pojedynczej precyzji mantysa posiada 23 bity, a w podwójnej precyzji 52 bity. Wzrost liczby bitów mantys liczb zmiennoprzecinkowych wpływa na ich precyzję, czyli dokładność odwzorowywania liczb rzeczywistych.

Mantysy są zapisywane w stałoprzecinkowym kodzie U1. Ponieważ mantysa jest prawie zawsze znormalizowana (z wyjątkiem wartości zdenormalizowanej, która jest przypadkiem szczególnym liczby zmiennoprzecinkowej IEEE 754), to jej wartość liczbowa zawiera się pomiędzy 1 a 2. Wynika stąd, iż pierwszy bit całkowity mantysy zawsze wynosi 1. Skoro tak, to nie musi on być zapamiętywany - będzie automatycznie odtwarzany w czasie wykonywania obliczeń na liczbie zmiennoprzecinkowej. W polu mantysy zapamiętujemy tylko bity ułamkowe. Dzięki tej prostej sztuczce zyskujemy jeden dodatkowy bit mantysy - zwiększamy jej rozdzielczość do 24 bitów dla formatu pojedynczej precyzji i do 53 bitów dla formatu podwójnej precyzji. Sposób ten nie jest wcale nowy - zastosował go już w 1936 roku niemiecki konstruktor Konrad Zuse w swoich komputerach.

 

Wartość liczby IEEE 754

Wartość liczby IEEE 754 obliczamy wg poznanych dotychczas zasad. Z kodu wydzielamy poszczególne pola znaku z, cechy c i mantysy m. Odczytana mantysa zawiera tylko bity ułamkowe. Dodajemy zatem na początku 01 i przecinek. W wyniku otrzymujemy dodatnią liczbę stałoprzecinkową w kodzie U1. Teraz obliczamy wartość cechy i mantysy, a następnie wyliczamy wartość liczby wg wzoru:

 

L(IEEE 754) = (-1)zm2c

 

Dla przykładu policzymy wartości kilku liczb w pojedynczej precyzji (dla podwójnej precyzji rachunki są identyczne, lecz bardziej uciążliwe do przeprowadzenia z uwagi na większą liczbę bitów).

 

Przykład:

Obliczyć wartość dziesiętną liczby zmiennoprzecinkowej: 01000010110010000000000000000000(IEEE 754).

Kod binarny dzielimy na poszczególne pola zawierające kolejno znak, cechę oraz bity ułamkowe mantysy:

 

0 10000101 10010000000000000000000
z cecha bity ułamkowe mantysy

z = 0 - liczba jest dodatnia
c = 10000101(BIAS=127) = 133 - 127 = 6
m = 01,10010000000000000000000(U1) = 19/16

 

Mamy wszystkie niezbędne składniki, wyliczamy wartość liczby:

 

L(IEEE 754) = (-1)zm2c = (-1)0 × 19/16 × 26 = 25/16 × 26= 25 × 22 = 25 × 4 = 100(10)

01000010110010000000000000000000(IEEE 754) = 100(10).

 

Przykład:

Obliczyć wartość dziesiętną liczby zmiennoprzecinkowej : 11000001110110000000000000000000(IEEE 754).

Postępujemy identycznie jak w poprzednim przykładzie:

 

1 10000011 10110000000000000000000
z cecha bity ułamkowe mantysy

z = 1 - liczba jest ujemna
c = 10000011(BIAS=127) = 131 - 127 = 4
m = 01,10110000000000000000000(U1) = 111/16

L(IEEE 754) = (-1)zm2c = (-1)1 × 111/16 × 24 = - 27/16 × 24= -27(10)

11000001110110000000000000000000(IEEE 754) = -27(10).

 

Przykład:

Obliczyć wartość dziesiętną liczby zmiennoprzecinkowej : 10111110000000000000000000000000(IEEE 754).

 

1 01111100 00000000000000000000000
z cecha bity ułamkowe mantysy

z = 1 - liczba jest ujemna
c = 01111100(BIAS=127) = 124 - 127 = -3
m = 01,00000000000000000000000(U1) = 1

L(IEEE 754) = (-1)zm2c = (-1)1 × 1 × 2-3 = - 1/8 = -0,125(10)

10111110000000000000000000000000(IEEE 754) = -0,125(10).

 

Liczby zmiennoprzecinkowe wcale nie są takie straszne - pod warunkiem, że pilnie studiowałeś nasz artykuł. W przeciwnym razie na zawsze pozostaną dla ciebie tajemnicą...

Poniżej przedstawiam prosty program w języku Pascal, który pozwala zobaczyć wewnętrzną postać wprowadzonej liczby zmiennoprzecinkowej w standardzie IEEE 754 (program nie uwzględnia wartości specjalnych - ale może ty potrafisz go ulepszyć?). W programie wykorzystujemy fakt, iż komputer IBM PC przechowuje liczby zmiennoprzecinkowe w tym właśnie standardzie, zatem nic nie musimy przeliczać, wszystko robi za nas system.

 

Efekt uruchomienia programu
Demonstracja standardu zmiennoprzecinkowego IEEE 754
----------------------------------------------------
(C)2005 mgr Jerzy Walaszek           I LO w Tarnowie

Wpisz liczbe : -13257.25

11000110010011110010010100000000

1 10001100 10011110010010100000000
z cecha    mantysa

z = 1
c = 10001100 = 13
m = 01,10011110010010100000000 = 1.6183166504

Klawisz ENTER = KONIEC

 

program IEEE754;

{$APPTYPE CONSOLE}

type
  sp_ieee754 = record
    case value: integer of
      0 : (b : array[0..3] of byte);
      1 : (f : single);
    end;

var
  l_ieee754 : sp_ieee754;
  i,j,v,c,z : integer;
  s         : string;

begin
  writeln('Demonstracja standardu zmiennoprzecinkowego IEEE 754');
  writeln('----------------------------------------------------');
  writeln('(C)2005 mgr Jerzy Walaszek           I LO w Tarnowie');
  writeln;
  write('Wpisz liczbe : '); readln(l_ieee754.f);
  writeln;
//---------------------------------------
// Odczytujemy kolejne bity zapisu liczby
//---------------------------------------
  s := '';

  for i := 0 to 3 do
  begin
    v := l_ieee754.b[i];
    for j := 1 to 8 do
    begin
      s := char(48 + (v mod 2)) + s;
      v := v div 2;
    end;
  end;

  writeln(s);
  writeln;

  for i := 1 to 32 do
  begin
    write(s[i]);
    if (i = 1) or (i = 9) then write(' ');
  end;

  writeln;
  writeln('z cecha    mantysa');
  writeln;
//----------------------------------------------------
// Teraz wyznaczamy wartości poszczególnych składników
// Program nie uwzględnia wartości specjalnych !
//----------------------------------------------------
  z := (l_ieee754.b[3] and $80) shr 7;
  writeln('z = ',z);

  c := ((l_ieee754.b[3] and $7f) shl 1) or ((l_ieee754.b[2] and $80) shr 7) - 127;
  writeln('c = ',copy(s,2,8),' = ',c);

  v := $800000 or ((l_ieee754.b[2] and $7f) shl 16) or (l_ieee754.b[1] shl 8) or l_ieee754.b[0];
  writeln('m = 01,',copy(s,10,23),' = ',v / $800000:0:10);

  writeln;
  write('Klawisz ENTER = KONIEC'); readln;
end.

 

Zakres liczb IEEE 754

Gdy znamy budowę liczby zmiennoprzecinkowej w standardzie IEEE 754, z obliczeniem zakresu możliwych do zapisania w nim liczb nie będzie żadnego problemu. Po prostu musimy znaleźć największą cechę i największą mantysę i podstawić je do podanego wcześniej wzoru.

 

Liczby pojedynczej precyzji

Największa cecha posiada kod:

 

c = 11111110(BIAS=127)
c = 254 - 127
c = 127

 

Kod 11111111(BIAS=127) = 255 - 127 = 128 jest zarezerwowany dla specjalnych sytuacji, zatem nie możemy go wykorzystać na cechę liczby zmiennoprzecinkowej.

 

Największa mantysa osiada kod:

 

m = 01,11111111111111111111111(U1)
m = (224 - 1) / 223

 

Obliczamy wartość największej liczby:

 

max(IEEE 754) = m × 2c
max(IEEE 754) = (224 - 1) / 223 × 2127
max(IEEE 754) = (224 - 1) × 2104
max(IEEE 754) = 3,4028234663852885981170418348452 × 1038

 

a po zaokrągleniu:

 

max(IEEE 754) = 3,4 × 1038

 

Ponieważ zmianą znaku możemy uzyskać tę samą wartość po stronie ujemnej, zakres liczb zmiennoprzecinkowych IEEE 754 w pojedynczej precyzji wynosi:

 

Zapamiętaj:

Zakres liczb zmiennoprzecinkowych IEEE 754 w pojedynczej precyzji

 

Z(IEEE 754) = - 3,4 × 1038 ... 3,4 × 1038

 

Liczby podwójnej precyzji

Dla liczby IEEE 754 podwójnej precyzji przeprowadzamy identyczne obliczenia:

 

c = 11111111110(BIAS=1023)
c = 2046 - 1023
c = 1023

m = 01,1111111111111111111111111111111111111111111111111111(U1)
m = (253 - 1) / 252

max(IEEE 754) = m × 2c
max(IEEE 754) = (253 - 1) / 252 × 21023
max(IEEE 754) = (253 - 1) × 2971
max(IEEE 754) = 1,797693134862315708145274237317 × 10308

 

a po zaokrągleniu:

 

max(IEEE 754) = 1,8 × 10308

 

Zapamiętaj:

Zakres liczb zmiennoprzecinkowych IEEE 754 w podwójnej precyzji

 

Z(IEEE 754) = - 1,8 × 10308 ... 1,8 × 10308

 

Precyzja liczb IEEE 754

Oprócz zakresu, na który wpływa głównie długość formatu bitowego cechy, dla liczb zmiennoprzecinkowych nie mniej ważnym parametrem jest precyzja zapisu, czyli z jaką dokładnością dana liczba może być reprezentowana. Precyzję podaje się najczęściej jako przybliżoną ilość dziesiętnych cyfr znaczących. Na przykład jeśli precyzja zapisu wynosi trzy cyfry dziesiętne, to liczby 856  92,4  1,53 zostaną zapamiętane dokładnie, natomiast liczby o większej ilości cyfr już nie: 85613 zostanie zapamiętane jako 856??, gdzie znaki ? reprezentują dowolne cyfry.

Precyzję zapisu liczby zawsze wyznacza ilość dostępnych bitów mantysy. Jedną cyfrę dziesiętną koduje (statystycznie) log2(10) bitów mantysy. Ułóżmy zatem proste proporcje:

Dla pojedynczej precyzji mantysa ma długość 24 bity:

 

1 cyfra dziesiętna --- log2(10) bitów
x cyfr dziesiętnych --- 24 bity

 

Stąd

 

x cyfr dziesiętnych = 24 / log2(10) = 24 / 3,32 = 7,2 cyfry

 

Zaokrąglamy wynik do liczby całkowitej i dla liczb w pojedynczej precyzji otrzymujemy 7 dziesiętnych cyfr znaczących.

Dla podwójnej precyzji mantysa ma długość 53 bity:

 

1 cyfra dziesiętna --- log2(10) bitów
x cyfr dziesiętnych --- 53 bity

 

Stąd

 

x cyfr dziesiętnych = 53 / log2(10) = 53 / 3,32 = 15,96 cyfry

 

Zaokrąglamy wynik do liczby całkowitej i dla liczb w podwójnej precyzji otrzymujemy 15-16 cyfr znaczących.

 

Zapamiętaj:

Liczby pojedynczej precyzji IEEE 754 oferują precyzję 7 cyfr dziesiętnych. Zatem nadają się one do bardzo prostych rachunków, gdzie nie wymagana jest zbyt duża dokładność.

Liczby podwójnej precyzji IEEE 754 oferują precyzję 15...16 cyfr dziesiętnych. Zatem nadają się do dokładnych obliczeń naukowych i inżynierskich. Stosuj je zawsze tam, gdzie wymagana jest duża dokładność końcowych wyników.

 

Wartości specjalne we formacie IEEE 754

Wartość zero

Zauważ, iż w normalny sposób nie można zapisać w formacie IEEE 754 wartości 0, ponieważ mantysa ma domyślną część całkowitą równą 1 - w polu mantysy zapamiętywane są jedynie bity ułamkowe. Dlatego zero jest specjalnym przypadkiem liczby zmiennoprzecinkowej, gdzie zarówno pole wykładnika jak i mantysy zawiera same 0. Bit znaku może przyjmować dowolną wartość (stąd możemy dostać dodatnie lub ujemne 0, jednakże przy porównaniu są one traktowane jak równe sobie).

 

Wartość ZERO pole
znaku
pole
cechy
pole
mantysy
0/1 0...0 0...0

 

Wartość zdenormalizowana

Jeśli wszystkie bity cechy mają wartość 0, lecz mantysa zawiera bity o wartościach 1 (w przeciwnym razie liczba zostanie potraktowana jak opisane wcześniej zero), to jest to tzw. zdenormalizowana liczba zmiennoprzecinkowa. W takim przypadku mantysa nie posiada domyślnej części całkowitej 1, lecz jest liczbą ułamkową, której bity zawarte są w polu formatu IEEE 754.

 

Wartość

zdenormalizowana

pole
znaku
pole
cechy
pole
mantysy
0/1 0...0 bity ułamkowe mantysy

 

 

Wartość zdenormalizowaną liczby zmiennoprzecinkowej liczymy według wzoru:

 

Pojedyncza precyzja

m = 00,(pole mantysy)(U1)

L = (-1)zm2-126

 

Stąd najmniejszą wartością zmiennoprzecinkową różną od zera jest:

 

00000000000000000000000000000001(IEEE 754)

m = 00,00000000000000000000001(U1)
m = 2-23

min(IEEE 754) = 2-23 × 2-126 = 2-149
min(IEEE 754) = 1,4012984643248170709237295832899 × 10-45
min(IEEE 754) = ±1,4 × 10-45

 

Podwójna precyzja

m = 00,(pole mantysy)(U1)

L = (-1)zm2-1022

 

Stąd najmniejszą wartością zmiennoprzecinkową różną od zera jest:

 

000000000000000000000000000000000000000000000000000000000000001(IEEE 754)

m = 00,0000000000000000000000000000000000000000000000000001(U1)
m = 2-52

min(IEEE 754) = 2-52 × 2-1022 = 2-1074
min(IEEE 754) = 4,9406564584124654417656879286822 × 10-324
min(IEEE 754) = ±4,9 × 10-324

 

Zapamiętaj:

Wartości zdenormalizowane pozwalają przedstawiać bardzo małe liczby zmiennoprzecinkowe, które bez tej opcji zostałyby zaokrąglone do 0. Zwiększa to precyzję wykonywanych operacji zmiennoprzecinkowych i jest cechą bardzo pożądaną. Liczbę zero można traktować jak liczbę zdenormalizowaną, w której mantysa wynosi 0.

 

Nieskończoność

Standard IEEE 754 pozwala reprezentować dodatnią i ujemną nieskończoność. Pole znaku określa, z którą nieskończonością mamy do czynienia - dodatnią czy ujemną. Cecha posiada wszystkie bity ustawione na 1 (maksymalna wartość cechy), a bity mantysy są wyzerowane.

 

Nieskończoność pole
znaku
pole
cechy
pole
mantysy
0/1 1...1 0...0

 

Wartość typu nieskończoność jest bardzo pożądana w systemie zmiennoprzecinkowym, ponieważ pozwala ona prowadzić obliczenia po wystąpieniu nadmiaru. Wyniki działań z nieskończonościami są dokładnie zdefiniowane w standardzie IEEE 754 - opisujemy je na końcu rozdziału.

 

Nieliczby

Standard IEEE 754 definiuje dwie specjalne wartości, które nie reprezentują liczb. Stąd nazywane są w literaturze terminem NaN (Not a Number - Nie Liczba). Nieliczby mogą być dwojakiego rodzaju - tzw. ciche - QNaN (ang. Quiet NaN) lub głośne SNaN (ang. Signaling NaN). W obu przypadkach cecha zawiera same 1, a pole mantysy zawiera bity 1. Jeśli najstarszy bit ułamkowy mantysy jest ustawiony na 1, to kod reprezentuje cichą nieliczbę - QNaN.

 

Cicha Nieliczba
QNaN
pole
znaku
pole
cechy
pole
mantysy
0/1 1...1 1X...X

 

Jeśli najstarszy bit mantysy ustawiony jest na 0, kod reprezentuje głośną nieliczbę:

 

Głośna Nieliczba
SNaN
pole
znaku
pole
cechy
pole
mantysy
0/1 1...1 0X...X

 

Nieliczby mają wiele zastosowań. Ciche nieliczby przechodzą przez działania arytmetyczne. Najczęściej oznaczają one wartość niezdefiniowaną. Głośne nieliczby powodują powstanie wyjątków w operacjach arytmetycznych. Najczęściej oznaczają one wartość niedozwoloną. Typowym zastosowaniem głośnych nieliczb jest wstępna inicjalizacja zmiennych. Jeśli programista nie wprowadzi do zmiennej wartości, czyli nie zainicjuje jej, to będzie ona zawierała wartość SNaN. Próba użycia takiej zmiennej w jakimkolwiek wyrażeniu arytmetycznym spowoduje wygenerowanie wyjątku i przerwanie obliczeń.

 

Wyniki operacji z wartościami specjalnymi

Standard IEEE 754 bardzo dokładnie precyzuje wyniki operacji, w których jednym z argumentów (lub obydwoma) jest wartość specjalna. W poniższej tabelce zebraliśmy najważniejsze zasady przeprowadzania takich operacji:

 

Operacja Wynik
n / ±∞ 0
±∞ × ±∞ ±∞
±wartość niezerowa / 0 ±∞
∞ + ∞
±0 / ±0 NaN
∞ - ∞ NaN
±∞ / ±∞ NaN
±∞ × 0 NaN

 

Zainteresowanych tym tematem odsyłamy do artykułu o komputerach Konrada Zuse.

 

Podsumowanie standardu IEEE 754

W poniższej tabelce podsumowujemy wszystkie możliwe wartości reprezentowane przez format IEEE 754. Więcej danych na temat standardu IEEE 754 znajdziesz w witrynie http://standards.ieee.org/.

 

Interpretacja kodu IEEE 754
Pole
znaku
Pole
cechy
Pole
mantysy
Wartość
0 0...0 0..0 +0 (zero dodatnie)
0 0...0 0...1
:
1...1
Dodatnia liczba zdenormalizowana
0 0...1
:
1...0
0...0
:
1...1 
Dodatnia liczba zmiennoprzecinkowa
0 1...1 0...0 +∞
0 1...1 0...01
:
01...1
SNaN (głośna nieliczba)
0 1...1 10...0
:
1...1
QNaN (cicha nieliczba)
1 0...0 0...0 -0 (zero ujemne)
1 0...0 0...1
:
1...1
Ujemna liczba zdenormalizowana
1 0...01
:
1...10
0...0
:
1...1
Ujemna liczba zmiennoprzecinkowa
1 1...1 0...0 -
1 1...1 0...01
:
01...1
SNaN (głośna nieliczba)
1 1...1 10...0
:
1...1
QNaN (cicha nieliczba)

 

Zadania

Zadanie 1 (średnio trudne)

Każdy współczesny procesor Pentium zintegrowany jest wewnętrznie z koprocesorem arytmetycznym, który wykonuje sprzętowo operacje na liczbach zmiennoprzecinkowych. Wewnętrznie stosuje on rozszerzony typ danych zmiennoprzecinkowych o następującej specyfikacji formatu:

 

Format rozszerzony zapisu zmiennoprzecinkowego koprocesora arytmetycznego
80 bitów - rozszerzona precyzja (1 bit)   b79 (15 bitów)   b78 ... b64 (BIAS=16383) (64 bity)   ,b63 ... b0 (U1)
Opis pół bitowych bit znaku bity kodu cechy bity ułamkowe mantysy

 

Na podstawie materiału przedstawionego w tym rozdziale wyznacz kolejno:

  1. Zakres możliwych do przedstawienia w tym formacie liczb dziesiętnych
  2. Najmniejszą dziesiętną liczbę zdenormalizowaną
  3. Precyzję zapisu, czyli liczbę znaczących cyfr dziesiętnych.

Zobacz dalej...

Przykładowy system zmiennoprzecinkowy | Wywiad z twórcą standardu IEEE 754, Williamem Kahanem



List do administratora Serwisu Edukacyjnego I LO

Twój email: (jeśli chcesz otrzymać odpowiedź)
Temat:
Uwaga: ← tutaj wpisz wyraz  ilo  , inaczej list zostanie zignorowany

Poniżej wpisz swoje uwagi lub pytania dotyczące tego rozdziału (max. 2048 znaków).

Liczba znaków do wykorzystania: 2048

W związku z dużą liczbą listów do naszego serwisu edukacyjnego nie będziemy udzielać odpowiedzi na prośby rozwiązywania zadań, pisania programów zaliczeniowych, przesyłania materiałów czy też tłumaczenia zagadnień szeroko opisywanych w podręcznikach.



   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

(C)2014 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.