在學習如何在計算機中表示浮點數時,我遇到了「偏差值」這個詞,我不太明白。什麼是浮點數的「偏差值」?
浮點數的偏差值與浮點數的指數部分的負值和正值有關。
浮點數的偏移值是127,這意味着總是將127添加到浮點數的指數部分。這樣做如何幫助確定指數是否爲負值或正值?
在學習如何在計算機中表示浮點數時,我遇到了「偏差值」這個詞,我不太明白。什麼是浮點數的「偏差值」?
浮點數的偏差值與浮點數的指數部分的負值和正值有關。
浮點數的偏移值是127,這意味着總是將127添加到浮點數的指數部分。這樣做如何幫助確定指數是否爲負值或正值?
在單精度浮點上,您可以獲得8位來存儲指數。不是將它作爲一個帶符號的二進制補碼存儲起來,而是決定只需在指數中加127即可(因爲最低的可能是8位有符號的是-127),並將其存儲爲無符號數。如果存儲值大於偏差,則表示指數的值爲正數,如果它低於偏差,則爲負數,如果相等,則爲零。
所以在IEEE格式,由於127點的偏差,如果指數字段是'00000000',那麼這意味着數的指數是-127? – 2017-03-21 19:24:37
@KennethWorden沒有,全零的指數值是特殊和數字解釋爲「非規範化」(這包括0本身)。 – 2017-10-27 17:22:44
b0lt已經解釋了偏差是如何工作的。有人猜測,也許你想知道爲什麼他們在這裏使用偏差表示,即使幾乎所有的現代計算機都基本上在其他地方使用二進制補碼(甚至不使用二進制補碼的機器,使用補碼或符號 - 大小,而不是偏見)。
IEEE浮點標準的目標之一是,您可以將浮點數的位作爲具有相同大小的(帶符號)整數進行處理,如果您將它們進行比較,則這些值將排序爲與它們表示的浮點數的順序相同。
如果對指數使用二進制補碼錶示,則小的正數(即具有負指數)看起來像是一個非常大的整數,因爲第二個MSB將被設置。通過使用偏差表示來代替,您不會遇到這種情況 - 浮點數中較小的指數總是看起來像一個較小的整數。
FWIW,這也是爲什麼浮點數通常先按符號排列,然後是指數,最後是最低有效位中的有效位數 - 這樣,您可以採用正浮點數,將這些位作爲整數,並對它們進行分類。當你這樣做的時候,結果將會有正確順序的浮點數。例如:
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
// some arbitrary floating point values
std::vector<double> vals = { 1e21, 1, 2.2, 2, 123, 1.1, 0.0001, 3, 17 };
std::vector<long long> ivals;
// Take those floating point values, and treat the bits as integers:
for (auto &&v : vals)
ivals.push_back(*reinterpret_cast<long long *>(&v));
// Sort them as integers:
std::sort(ivals.begin(), ivals.end());
// Print out both the integers and the floating point value those bits represent:
for (auto &&i : ivals)
std::cout << i << "\t(" << *reinterpret_cast<double *>(&i) << ")\n";
}
當我們運行這個,結果是這樣的:
4547007122018943789 (0.0001)
4607182418800017408 (1)
4607632778762754458 (1.1)
4611686018427387904 (2)
4612136378390124954 (2.2)
4613937818241073152 (3)
4625478292286210048 (17)
4638355772470722560 (123)
4921056587992461136 (1e+21)
正如你所看到的,即使我們整理它們爲整數,浮點數,這些位也代表按正確的順序出來。
這對浮點數有一定的限制。儘管所有(非古代)計算機都同意正數的表示形式,但有三種表示法(最近才用於有符號數字):有符號數,補碼和二進制補碼。
只要將這些位視爲一個整數並進行比較,就可以在使用整數的有符號幅度表示的計算機上正常工作。對於使用補碼或補碼的計算機,負數將按相反順序排序。由於這仍然是一個簡單的規則,所以編寫適用於它的代碼很容易。如果我們改變了sort
調用上面是這樣的:
std::sort(ivals.begin(), ivals.end(),
[](auto a, auto b) { if (a < 0.0 && b < 0.0) return b < a; return a < b; }
);
...這將然後正確的排序都正數和負數。例如,輸入:
std::vector<double> vals = { 1e21, 1, 2.2, 2, 123, 1.1, 0.0001, 3, 17, -0.001, -0.00101, -1e22 };
會產生一個結果:
-4287162073302051438 (-1e+22)
-4661071411077222194 (-0.00101)
-4661117527937406468 (-0.001)
4547007122018943789 (0.0001)
4607182418800017408 (1)
4607632778762754458 (1.1)
4611686018427387904 (2)
4612136378390124954 (2.2)
4613937818241073152 (3)
4625478292286210048 (17)
4638355772470722560 (123)
4921056587992461136 (1e+21)
是的,我也想知道爲什麼。這回答了。很有意思。謝謝。 – mudge 2010-05-14 16:18:36
@JerryCoffin:1優異的應答(特別是FP數目的組件內的順序的理由)。 – legends2k 2013-07-02 15:00:02
@JerryCoffin我不明白爲什麼浮點數可以作爲整數對待......我的意思是,相同的位的順序將保持每個數據類型不同的值。你能詳細說明嗎? – user1534664 2017-07-07 15:38:18
增加更多的細節上面的答案。
爲了表示0
,infinity
和NaN
(Not-a-Number)在浮點數,IEEE決定使用特殊的編碼值。
如果指數字段的所有位均設置爲0,則浮點數爲0.0。
如果指數字段的所有位均設置爲1,並且小數部分的所有位均爲0,則浮點數爲無窮大。
如果指數字段的所有比特被設置爲1和小數部分的所有位不等於0,則該浮點數是NaN的。
因此,在單精度我們有8位來表示指數字段和有2個特殊值,所以我們基本上具有能夠以指數來表示256 - 2 = 254
值。因此,我們可以有效地代表-126到127的指數,即254個值(126 + 127 + 1),1增加了0.1
有關這個問題的另一個有趣的閱讀是這個維基百科的文章:HTTPS:/ /en.wikipedia.org/wiki/IEEE_754-1985 – nbro 2016-03-19 14:11:27