浮點數在計算機中是如何表示的

2021-02-24 腳本之家

來源:編程珠璣

前言

相比int等整型,float等浮點類型的表示和存儲較為複雜,但它又是一個無法迴避的話題,那麼就有必要對浮點一探究竟了。在計算機中,一般用IEEE浮點近似表示任意一個實數,那麼它實際上又是如何表示的呢?

下面的表達式裡,i的值是多少,為什麼?如果你不確定答案,那麼你應該好好看看本文。

float f = 8.25f;
int i = *(int*)&f;

IEEE浮點表示

IEEE浮點標準用

的形式近似表示一個數。並且將浮點數的位表示劃分為三個欄位:

符號(sign)s決定這個數是負數(s=1)還是正數(s=0)。可以用一個單獨的符號s直接編碼符號s。

尾數(signficand)M是一個二進位小數,它的範圍是1~2-ξ或者是0~1-ξ。
n位小數欄位編碼尾數M。

階碼(exponent)E的作用是對浮點數加權,這個權重是2的E次冪(可能是負數)。k位的階碼欄位 編碼階碼E。

在單精度浮點格式(c語言的float)中,s,exp和frac欄位分別為1位,8位和23位,而雙精度浮點格式(c語言中的double)中,s,exp和frac欄位分別為1位,11位和52位。
一個浮點數的常見比特位表示如下:

s(31)exp(30~23)frac(22~0)s(63)exp(62~52)frac(51~0)

而根據exp的值,被編碼的值可以分為三大類不同的情況。下面進行一一解釋。

情況1:規格化的值

即最普遍的情況,當exp,即階碼域既不為全0,也不為全1的情況。在這種情況下,階碼欄位解釋為以偏置(biased)形式表示有符號整數,即E=exp-Bias,exp是無符號數(1~254)。Bias是一個等於的偏置值,對於單精度來說,k=23,Bias=127,因此E的範圍是-126~+127。

frac被描述為小數值,且0≤frac<1,其二進位表示為0.frac。尾數定義為 M=1+frac ,則M=1.frac。那麼就有1≤M<2,由於總是能夠調整階碼E,使得M在範圍1≤M<2,所以不需要顯示的表示它,這樣還能獲得一個額外的精度位。也就是說,在計算機內部保存M時,默認這個數的第一位總是1,因此可以被捨去,只保存後面的frac部分,等到讀取的時候,再把第一位的1加上去。

情況2:非規格化的值

當exp,即階碼域為全0時,所表示的數便為非規格化的值,該情況下的階碼值E=1-Bias(注:為從非格式化值轉換到格式化值提供了一種方法)。尾數M=frac

非規格化的數有兩個作用。

情況3:特殊值

有兩種

浮點數的範圍和有效位

對於浮點數,其能表示的數值範圍和其有效位如下

類型比特位數值範圍有效位float32-3.410^38~+3.410^386~7位double64-1.710^-308~1.710^30815~16位long double128-1.210^-4932~1.210^493218~19位

可見同比特位數的整型(例如int)要比浮點數(例如float)能表示的數值範圍要小很多,但是需要注意的,雖然浮點數能表示的範圍大,但是 它卻不能精確表示在其範圍內的所有實數,也就是說,它只能保證有效位的值是精確的,當表示的數值(小數部分)超過有效位時,所表示的數是無法保證精確的,甚至可以說是錯誤的。
那麼浮點數的數值範圍和有效位是如何得到的呢?

浮點數的數值範圍計算

有了前面了基礎,我們就可以來計算浮點數的數值範圍了。以單精度(float)為例,我們知道它的指數範圍(即E)為-126~+127,而M的範圍為1≤M<2,實際上,對於單精度,1≤M≤2-2^(-23)(注:23為frac欄位所佔的比特位)。那麼我們就可以得到單精度的最大值為:
同理,我們可以得到單精度的最小值為:

我們僅僅以單精度為例,用同樣的方法可以計算其他精度的浮點數數值範圍,在此不再贅述。

浮點數的有效位

有效位也可以理解為我們常說的精度。浮點數的精度是由尾數的位數來決定的。
對於單精度(float),它的尾數為23位,而2^23=8388608,共7位,也就是說最多能有7位有效數字,但至少能保證6位,因此其有效位為6~7位。當然我們可以通過下面的內容進一步理解。以下計算結果保留10位小數。



觀察a和b的結果可以發現,0.0000001和0.0000002之間的其他數是沒有辦法通過單精度浮點數來精確表示的,也就是說,只有到小數點後面7位的值才是精確的,同理,觀察b和c的結果,0.0000002到0.0000004之間的其他數也是不能通過單精度浮點數精確表示的,更不幸地是,這之間的數,甚至只能精確到第6位。

這也就有了單精度浮點數的有效位為6~7位的結論。根據相似的方法,我們同樣可以得到雙精度浮點數的有效位為15~16位的結論,這裡不再贅述。

浮點數在內存中的存儲

了解了這麼多,我們來看一下一個小數究竟是如何在內存中存儲的。以float f = 8.5f為例。其二進位表示為,可見指數實際值為3,則根據E=exp-Bias,可知exp=E+Bias=3+127=130,根據M=1+frac,可知,frac=M-1=0.0001(二進位)而

因此不難得到,8.5的在內存中的存儲情況為:

sexpfrac01000 00100001 0000 0000 0000 0000 000

如果這個時候把這個值作為整型使用,是多少呢?沒錯,是1091043328

#include<stdio.h>
int main(int argc,char *argv[])
{
    float f=8.5f;
    int *i = (int*)&f;
    printf("%d
",*i);
    return 0;
}

再說幾句

關於浮點數,需要再說幾句:

返回 上一級 搜索「Java 女程式設計師 大數據 留言送書 運維 算法 Chrome 黑客 Python JavaScript 人工智慧 女朋友 MySQL 書籍 等關鍵詞獲取相關文章推薦。

相關焦點

  • python浮點數表示專題及常見問題 - CSDN
    浮點數用來存儲計算機中的小數,與現實世界中的十進位小數不同的是,浮點數通過二進位的形式來表示一個小數。要理解計算機中浮點數的表示規則,先來看現實世界中十進位小數是如何表示的:1.234 = 1 + 1/10 + 2/100 + 3/1000可以用下面的公式來表示:$$d = \sum_{i=-n}^m10^i*d_i$$其中 $d_i$ 是十進位中 0~9 的數字。
  • 一文讀懂浮點數
    小數在日常生活中經常用到,比如超市中商品的價格、零件的尺寸等等,計算機作為計算的工具,也必然要支持小數。在計算機中,小數的類型有兩種,一種是定點數,即小數點後面的位數是固定的,最典型的定點數就是 BCD 編碼;還有一種是浮點數,浮點數的小數點是浮動的,小數點後面的小數位數不固定,這也是本文的主角。
  • 15 張圖帶你深入理解浮點數
    浮點數為什麼會存在 -0?infinity 和 NaN 又是怎麼表示的?如果現在不會,那這篇文章正好可以為你解惑。1、什麼是浮點數我們知道,數學中並沒有浮點數的概念,雖然小數看起來像浮點數,但從不這麼叫。那為什麼計算機中不叫小數而叫浮點數呢?
  • 看完這篇文章,你肯定理解什麼是浮點數了!
    浮點數是我們在編程中常用的一個數據類型,不知道大家想過沒有,它為什麼叫做float呢?還有,計算機對浮點數的內部表示方法IEEE 874到底是怎麼回事?要徹底理解浮點數,需要從計算機的底層存儲開始。假設有一個32 bit的計算機,需要你來設計一個支持存儲「小數」的方案,你會怎麼辦呢?
  • 雙精度(64位)浮點數轉單精度(32位)浮點數
    1、浮點數格式: 64位浮點數(雙精度)格式為:(來自:http://baike.baidu.com/item/雙精度浮點數)
  • 2012計算機大綱解析之計算機組成原理
    一、     大綱變化2012年計算機統考的計算機組成原理部分變化處數較多,主要出現在浮點數、存儲器、指令流水線以及I/O接口,具體如下:2011年大綱2012年大綱變動二、數據的表示和運算二、數據的表示和運算無變化(三) 浮點數的表示和運算(三) 浮點數的表示和運算
  • 你應該知道的浮點數基礎知識
    當然 原文中的投票最高的回答解釋的非常好,但博主第一次看的時候是一頭霧水,因為大部分基礎知識已經還給大學老師了。所以,本著知其然還要知其所以然的態度,博主做了一個詳盡的分析和思路整理過程。也希望讀者能夠從0開始解釋這個詭異現象的原因。現在讓我們複習大學計算機基礎課程。如果你熟練掌握了浮點數向二進位表達式轉換的方法,那麼你可以跳過這節。Sign(1bit):表示浮點數是正數還是負數。
  • 【第1081期】JavaScript 浮點數陷阱及解法
    本文幫你理清這背後的原理以及解決方案,還會向你解釋JS中的大數危機和四則運算中會遇到的坑。浮點數的存儲首先要搞清楚 JavaScript 如何存儲小數。和其它語言如 Java 和 Python 不同,JavaScript 中所有數字包括整數和小數都只有一種類型 — Number。
  • JavaScript浮點數陷阱,你需要了解一下
    本文幫你理清這背後的原理以及解決方案,還會向你解釋js中的大數危機和四則運算中會遇到的坑。浮點數的存儲首先要搞清楚 JavaScript 如何存儲小數。和其它語言如 Java 和 Python 不同,JavaScript 中所有數字包括整數和小數都只有一種類型 — Number。
  • 今天學Python第三課常用的數據類型有三種字符串,整數,浮點數
    浮點數整數是不帶小數點的純數字,那麼帶小數點的純數字怎麼表示呢?Python江湖中,將帶有小數點的純數字定義為浮點數。 它是我們從常見的數據類型之一。浮點數是顯而易見的,它比整數多了一個小數點【.】,下列代碼中的數字都是浮點數。3.141592695.27999.00浮點數,英文稱為float。
  • 數字限制了數字計算機建模的精確程度!那該怎麼辦呢?
    在發表在《Advanced Theory and Simulations》上的研究表明,數字計算機不能可靠地再現廣泛存在的「混沌系統」行為。這一基本限制可能會對高性能計算(HPC)和機器學習在高性能計算中的應用產生影響。UCL計算科學中心主任Peter Coveney教授和研究合著者說:我們的研究表明,混沌動系統的行為比任何數字計算機能捕捉到的更豐富。
  • 計算機組成原理知識大綱
    計算機組成原理知識大綱 第一章 計算機體系概述
  • Python實現一個類似range函數的浮點數生成器 - python高手養成
    Python實現浮點數生成器通常,我們使用range()函數來生成一個整形數列表,函數中我們可以自定義起始值、結束值和步進範圍。那麼,需求來了,我們能否實現一個類似range(start, end, step)函數的浮點數生成器。思路是這樣的:自定義一個類,添加其屬性start、end、step,分別表示浮點數起始值、結束值、步長值。
  • 計算機中信息的表示與處理
    信息的編碼方式 在計算機中信息都是以0、1兩種數據來表示的,大家都知道,但是就是這兩個簡單的0、1如何實現了計算機的強大計算呢?這就涉及到了計算機中信息的表達和處理。在大學計算基礎課上,開始就涉及了二進位、八進位、十進位、十六進位等進位之間的轉換方式。
  • 統考計算機組成原理重難點複習指導
    3、能夠運用計算機組成的基本原理和基本方法,對有關計算機硬體系統中的理論和實際問題進行計算、分析,並能對一些基本部件進行簡單設計。  二、知識點解析  在計算機組成原理方面,主要考查計算機系統基礎知識、數據的表示和運算、存儲器層次結構、指令系統、中央處理器、總線、輸入輸出系統。
  • 單精度浮點數與十六進位轉換
    #include <stdio.h>/*--十六進位到浮點數
  • 因為不理解混沌,計算機預測模型可能鑄成大錯
    甚至對於非常簡單的混沌系統,計算機使用的數字也可能導致不明顯但影響巨大的錯誤。」幾個世紀以來,理論家們一直在思考,非常小的影響如何會像滾雪球一樣,在下遊形成非常大的影響。在混沌理論中,這一著名的現象被稱為「蝴蝶效應」:打個比方,一隻蝴蝶在一個地方的輕微地扇動一下翅膀,會導致在另一個地方產生龍捲風。
  • Python中數據類型,你知道多少
    print(10 + '20')在Python中,有如下基本的數據類型:整型4.4.2 浮點數浮點數的有效數字最長17位,超過17位就用科學計數法表示num01=0.000000000000000000123num02=1000000000000000000000.123
  • 淺談java的浮點數精度問題
    問題大概情況可以通過如下代碼理解:得到的結果如下:f=2.0015E7d=2.0015E7d2=2.0014999E7從輸出結果可以看出double 可以正確的表示20014999 ,而float 沒有辦法表示20014999 ,得到的只是一個近似值。這樣的結果很讓人訝異。