Odwzorowanie liczby zmiennoprzecinkowej IEEE

Język Microsoft C++ (MSVC) jest zgodny ze standardami liczbowymi IEEE. Standard IEEE-754 opisuje formaty zmiennoprzecinkowe, sposób reprezentowania liczb rzeczywistych na sprzęcie. Istnieje co najmniej pięć formatów wewnętrznych dla liczb zmiennoprzecinkowych, które można przedstawić w sprzęcie przeznaczonym dla kompilatora MSVC. Kompilator używa tylko dwóch z nich. Formaty pojedynczej precyzji (4 bajtów) i podwójnej precyzji (8 bajtów) są używane w MSVC. Pojedyncza precyzja jest deklarowana przy użyciu słowa kluczowego float. Podwójna precyzja jest deklarowana przy użyciu słowa kluczowego double. Standard IEEE określa również format o połowę precyzji (2 bajty) i czterobajtowej precyzji (16 bajtów) oraz format podwójnej dokładności rozszerzonej (10 bajtów), który niektóre kompilatory języka C i C++ implementują jako long double typ danych. W kompilatorze long double MSVC typ danych jest traktowany jako odrębny typ, ale typ magazynu jest mapowany na double. Istnieje jednak obsługa języka wewnętrznego i zestawu na potrzeby obliczeń korzystających z innych formatów, w tym formatu o podwójnej precyzji rozszerzonej, gdzie jest obsługiwana przez sprzęt.

Wartości są przechowywane w następujący sposób:

Wartość Przechowywane jako
pojedyncza precyzja bit znaku, wykładnik 8-bitowy, 23-bitowy znak
podwójna precyzja bit znaku, wykładnik 11-bitowy, 52-bitowy znak

W formatach o pojedynczej precyzji i podwójnej precyzji przyjmuje się, że w części ułamkowej przyjęto założenie, że 1 jest wiodące. Część ułamkowa jest nazywana znakiem znakowym (czasami nazywana mantissa). Ten wiodący 1 nie jest przechowywany w pamięci, więc znaki są rzeczywiście 24 lub 53 bity, mimo że jeden mniej bit jest przechowywany. Format podwójnej dokładności rozszerzonej przechowuje ten bit.

Wykładniki są stronnicze o połowę ich możliwej wartości. Oznacza to, że odejmiesz tę stronniczą od przechowywanego wykładnika, aby uzyskać rzeczywisty wykładnik. Jeśli przechowywany wykładnik jest mniejszy niż stronniczy, jest to w rzeczywistości ujemny wykładnik.

Wykładniki są stronnicze w następujący sposób:

Wykładnik Stronniczy przez
8-bitowa (pojedyncza precyzja) 127
11-bitowa (podwójna precyzja) 1023

Te wykładniki nie są potęgami dziesięciu; są to moce dwóch. Oznacza to, że 8-bitowe przechowywane wykładniki mogą wahać się od -127 do 127, przechowywane jako 0 do 254. Wartość 2127 jest w przybliżeniu równoważna 1038, co jest rzeczywistym limitem pojedynczej precyzji.

Znak jest przechowywany jako ułamek binarny formularza 1.XXX ... . Ten ułamek ma wartość większą lub równą 1 i mniejszą niż 2. Liczby rzeczywiste są zawsze przechowywane w znormalizowanym formularzu. Oznacza to, że znak jest przesunięty w lewo tak, że bit o wysokiej kolejności znaku jest zawsze 1. Ponieważ ten bit jest zawsze 1, przyjmuje się ,że (nie jest przechowywany) w formatach o pojedynczej precyzji i podwójnej precyzji. Zakłada się, że punkt binarny (nie dziesiętny) znajduje się po prawej stronie wiodącego 1.

Format reprezentacji zmiennoprzecinkowych jest następujący:

Format bajt 1 bajt 2 bajt 3 bajt 4 ... bajt n
pojedyncza precyzja SXXXXXXX XMMMMMMM MMMMMMMM MMMMMMMM
podwójna precyzja SXXXXXXX XXXXMMMM MMMMMMMM MMMMMMMM ... MMMMMMMM

S reprezentuje bit znaku, Xs są stronniczymi bitami wykładniczymi, a Ms to bity znakowe. Bit po lewej stronie jest zakładany w formatach o pojedynczej precyzji i podwójnej precyzji.

Aby prawidłowo przesunąć punkt binarny, należy najpierw usunąć wykładnik, a następnie przenieść punkt binarny w prawo lub w lewo odpowiednią liczbę bitów.

Wartości specjalne

Formaty zmiennoprzecinkowe obejmują niektóre wartości, które są traktowane specjalnie.

Zero

Nie można znormalizować zera, co sprawia, że nie jest możliwe do przedstawiania w znormalizowanej postaci wartości o pojedynczej precyzji lub podwójnej precyzji. Specjalny wzorzec bitowy wszystkich zer reprezentuje wartość 0. Istnieje również możliwość reprezentowania wartości -0 jako zera z zestawem bitów znaku, ale -0 i 0 zawsze są porównywane jako równe.

Infinities

Wartości +∞ i −∞ są reprezentowane przez wykładnik wszystkich i znakowe, które są zerami. Dodatnie i ujemne są reprezentowane przy użyciu bitu znaku.

Nieprawidłowości podrzędne

Możliwe jest reprezentowanie liczb o mniejszej wielkości niż najmniejsza liczba w postaci znormalizowanej. Są one nazywane liczbami podrzędnymi lub denormalizowymi . Jeśli wykładnik ma wszystkie zera, a znak nie jest zerowy, to niejawny wiodący bit znaku jest uważany za zero, a nie jeden. Precyzja liczb podrzędnych spada, ponieważ liczba zer wiodących w znakach rośnie.

NaN — nie liczba

Istnieje możliwość reprezentowania wartości, które nie są liczbami rzeczywistymi, takimi jak 0/0, w formacie zmiennoprzecinkowym IEEE. Wartość tego rodzaju nosi nazwę NaN. Wartość NaN jest reprezentowana przez wykładnik wszystkich i niezerowy znak. Istnieją dwa rodzaje sieci NaNs, ciche sieci NaNs lub QNaNs oraz sygnalizujące sieci NaNs lub SNaNs. Ciche sieci NaN mają wiodącą wartość w znaku i są propagowane za pomocą wyrażenia. Reprezentują one nieokreśloną wartość, taką jak wynik dzielenia przez nieskończoność lub mnożenie nieskończoności przez zero. Sygnalizowanie sieci NaN ma wiodące zero w znaku. Są one używane do operacji, które nie są prawidłowe, aby zasygnalizować wyjątek sprzętu zmiennoprzecinkowego.

Przykłady

Poniżej przedstawiono kilka przykładów w formacie pojedynczej precyzji:

  • Dla wartości 2 bit znaku ma wartość zero. Przechowywany wykładnik wynosi 128 lub 1000 0000 w pliku binarnym, czyli 127 plus 1. Przechowywane znaki binarne to (1.) 000 0000 0000 0000 0000 0000 0000, co ma implikowane wiodące 1 i punkt binarny, więc rzeczywisty znak jest jednym.

    Wartość Wzór Reprezentacja binarna Szesnastkowy
    2 1 * 21 0100 0000 0000 0000 0000 0000 0000 0000 0x40000000
  • Wartość -2. Taki sam jak +2 z wyjątkiem tego, że bit znaku jest ustawiony. To samo dotyczy wartości ujemnej wszystkich liczb zmiennoprzecinkowych w formacie IEEE.

    Wartość Wzór Reprezentacja binarna Szesnastkowy
    -2 -1 * 21 1100 0000 0000 0000 0000 0000 0000 0000 0xC0000000
  • Wartość 4. Ten sam znakowy wykładnik zwiększa się o jedną (stronnicza wartość to 129 lub 100 0000 1 w pliku binarnym.

    Wartość Wzór Reprezentacja binarna Szesnastkowy
    4 1 * 2 2 0100 0000 1000 0000 0000 0000 0000 0000 0x40800000
  • Wartość 6. Ten sam wykładnik, znakowy jest większy o połowę. To (1.) 100 0000 ... 0000 0000, co, ponieważ jest to ułamek binarny, wynosi 1 1/2, ponieważ wartości cyfr ułamkowych to 1/2, 1/4, 1/8 itd.

    Wartość Wzór Reprezentacja binarna Szesnastkowy
    6 1,5 * 2 2 0100 0000 1100 0000 0000 0000 0000 0000 0x40C00000
  • Wartość 1. Ten sam znak jak inne moce dwóch, stronniczy wykładnik jest jeden mniejszy niż dwa na 127, lub 011 1111 1 w pliku binarnym.

    Wartość Wzór Reprezentacja binarna Szesnastkowy
    1 1 * 20 0011 1111 1000 0000 0000 0000 0000 0000 0x3F800000
  • Wartość 0,75. Wykładnik stronniczy wynosi 126, 011 1111 0 w pliku binarnym, a znak jest (1.) 100 0000 ... 0000 0000, czyli 1 1/2.

    Wartość Wzór Reprezentacja binarna Szesnastkowy
    0.75 1,5 * 2–1 0011 1111 0100 0000 0000 0000 0000 0000 0x3F400000
  • Wartość 2,5. Dokładnie tak samo jak dwa, z wyjątkiem tego, że bit reprezentujący 1/4 jest ustawiony w znaku.

    Wartość Wzór Reprezentacja binarna Szesnastkowy
    2,5 1.25 * 21 0100 0000 0010 0000 0000 0000 0000 0000 0x40200000
  • 1/10 to powtarzający się ułamek w pliku binarnym. Znak jest nieco mniejszy niż 1,6, a stronniczy wykładnik mówi, że 1,6 ma być podzielone przez 16. (Jest to 011 1101 1 w pliku binarnym, czyli 123 w przecinku). Prawdziwy wykładnik wynosi 123 - 127 = -4, co oznacza, że współczynnik, za pomocą którego należy się pomnożyć, wynosi 2–4 = 1/16. Przechowywane znaki są zaokrąglane w ostatnim bitzie w celu reprezentowania niereprezentowalnej liczby tak dokładnie, jak to możliwe. (Przyczyna, dla którego wartości 1/10 i 1/100 nie są dokładnie reprezentowane w pliku binarnym, jest podobna do przyczyny, że wartość 1/3 nie jest dokładnie reprezentowana w liczbach dziesiętnych).

    Wartość Wzór Reprezentacja binarna Szesnastkowy
    0.1 1.6 * 2-4 0011 1101 1100 1100 1100 1100 1100 1101 0x3DCCCCCD
  • Zero jest specjalnym przypadkiem. Używa formuły dla minimalnej możliwej wartości dodatniej reprezentującej wszystkie zera.

    Wartość Wzór Reprezentacja binarna Szesnastkowy
    0 1 * 2-128 0000 0000 0000 0000 0000 0000 0000 0000 0x00000000

Zobacz też

Dlaczego liczby zmiennoprzecinkowe mogą tracić dokładność