2011-10-04 72 views
16

我讀過他們存儲在尾數和指數的形式浮點數如何存儲在內存中?

我讀過this document但我什麼都聽不懂。

+1

您鏈接到該文件解釋它,而明確。你覺得什麼特別難以理解? –

+1

@MichaelBorgwardt不,現在還不清楚。它解釋了在介紹一個需要這個解釋的問題之後指數是如何被存儲的('但是如果這個數字是零?'......哦,親愛的')。就像那些犯罪故事,其中的竅門是他們沒有向你顯示所有的信息,但故事中的主角知道他們。 – xanatos

回答

25

,瞭解他們是如何存儲,你必須先了解它們是什麼,什麼樣的,他們的目的是處理值。

與整數不同,浮點值旨在表示非常小的值以及非常大的值。對於正常的32位浮點值,這對應的值範圍從 1.175494351 * 10^-38 3.40282347 * 10^+ 38

顯然,僅使用32位,不可能將這些數字中的每個數字都存儲起來。

說到表示法,您可以將所有常規浮點數看作1.0到(幾乎)2.0範圍內的值,並以2的冪次進行縮放。所以1.0是,只需 1.0 * 2^0。 2。0是 1.0 * 2^1。 -5.0是 -1.25 * 2^2

那麼,這需要儘可能有效地對此進行編碼?我們真的需要什麼?

  • 表達式的符號。
  • 指數
  • 值在1.0到(幾乎)2.0的範圍內。這就是所謂的「尾數」,即有效數字。

根據IEEE-754浮點標準,其編碼如下。

  • 該符號是單個位。
  • 指數存儲爲無符號整數,對於32位浮點值,此字段爲8位。 1代表最小的指數,「全1」代表最大的指數。 (0和「全1」用於編碼特殊值,見下文)。中間值(127,在32位情況下)表示零,這也被稱爲偏差
  • 查看尾數(1.0和(幾乎)2.0之間的值)時,可以看到所有可能的值都以「1」開頭(都是十進制和二進制表示形式)。這意味着存儲它是沒有意義的。其餘的二進制數字存儲在整數字段中,在32位的情況下,該字段是23位。

除了正常浮點值,也有一些特殊值:

  • 零編碼有兩個指數和尾數爲零。符號位用於表示「加零」和「減零」。當一個操作的結果非常小時,減零是有用的,但是知道操作來自哪個方向仍然很重要。
  • 正負無窮 - 用「全1」指數和零尾數字段表示。
  • 非數字(NaN) - 使用「全部1」指數和非零尾數表示。
  • 非標準化數字 - 小於最小正常數字的數字。使用零指數字段和非零尾數表示。具有這些數字的特殊情況是,精度(即數值可以包含的數字的數量)會降低數值越小,這僅僅是因爲在尾數中沒有空間。

最後,以下是具體例子少數(所有值都以十六進制):

  • 1.0:3f800000
  • -1234.0:c49a4000
  • 100000000000000000000000.0:65a96816
6

通俗地說,它基本上是二進制的scientific notation。正式標準(詳情)爲IEEE 754

+5

+1但維基不是正式標準,它至多是對正式標準的解釋:-) :-) – xanatos

+4

而C不需要IEEE浮點數。 –

3
typedef struct { 
     unsigned int mantissa_low:32;  
     unsigned int mantissa_high:20; 
     unsigned int exponent:11;   
     unsigned int sign:1; 
    } tDoubleStruct; 

double a = 1.2; 
tDoubleStruct* b = reinterpret_cast<tDoubleStruct*>(&a); 

是記憶是如何設置的,如果編譯器使用IEEE 754雙精度這是當今大多數系統上C雙鍵默認的一個例子。

這裏是基於C的二進制形式,更好地閱讀 wikipedia about double precision來理解它。

+1

這是一種可能性,但不是唯一的可能性。 –

2

有許多不同的浮點格式。它們中的大多數具有一些共同的特徵:符號位,專用於存儲指數的一些位,以及專用於存儲有效位(也稱爲尾數)的一些位。

IEEE浮點標準試圖定義可以在各種系統上實現的單一格式(或更確切地說幾種尺寸格式)。它還定義了可用的操作及其語義。它被很好地吸引住了,你可能遇到的大多數系統可能都使用IEEE浮點。但其他格式仍在使用中,以及不完整的IEEE實現。 C標準提供可選的支持IEEE,但沒有強制它。

1

尾數代表數字的最高有效位。

指數代表要在尾數上執行多少次換檔才能獲得數字的實際值。

編碼指定如何表示尾數的符號和指數符號(基本上是左移還是右移)。

您引用的文檔指定了使用最廣泛的IEEE編碼。

0

它是實現定義的,儘管IEEE-754是迄今爲止最常見的。

要確保IEEE-754使用:

    用C
  • ,使用#ifdef __STDC_IEC_559__
  • 在C++中,使用std::numeric_limits<float>::is_iec559常量