您現在的位置是:首頁 > 武術

浮點數和定點數是如何被計算機儲存的?

  • 由 JavaEdge 發表于 武術
  • 2022-01-04
簡介那32位元,能表示所有實數嗎

定點數採取了什麼方式

日常開發更多用到的都是實數。如電商商品價格一般9塊9。

浮點數的不精確性

能不能用二進位制表示所有實數,然後在二進位制下計算它的加減乘除呢?

開啟Chrome的Console,輸入“0。3 + 0。6”的結果:

浮點數和定點數是如何被計算機儲存的?

這麼簡單的一個加法,在JavaScript裡面,算出來的結果居然不是準確的0。9,而是0。8999999999999999,why?

計算機通常用16/32位元(bit)表示一個數。那32位元,能表示所有實數嗎?

顯然不能。32個位元,只能表示2^32個數,差不多40億。超過這個數,就會有兩個不同的數的二進位制表示相同 。計算機就會一籌莫展,不知道這個數到底是啥。

40億個數看起來很多,但比起無限多的實數集合也就渺小了。

到底應該讓這40億個數對映到實數集合上的哪些數,在實際應用中才能最划得來?

定點數

直觀想法,用4位元表示0~9的整數,則32位元即可表示8個這樣的整數。

然後把最右邊的2個0~9的整數,當成小數部分;把左邊6個0~9的整數,當成整數部分。這樣,我們就可以用32個位元,來表示從0到999999。99這樣1億個實數了。

浮點數和定點數是如何被計算機儲存的?

這種二進位制表示十進位制的編碼方式,叫BCD編碼(Binary-Coded Decimal)。

最常用的是在超市、銀行這樣需要用小數記錄金額的情況裡。超市小數最多到分。這樣的表示方式,直觀清楚,滿足小數部分計算。

缺點

浪費

本來32個位元我們可以表示40億個不同的數,但是在BCD編碼下,只能表示1億個數,要精確到分,那麼能夠表示的最大金額也就是到100萬。

貨幣單位是人民幣或者美元還好,辛巴威幣數量就不夠用了。

無法同時表示很大的數和很小的數

有時候我們想要表示商品的金額,關心9。99這樣小數字;有時候,物理學運算,需要表示光速,即 3×10^83×108 這樣很大的數字。

有沒有一個辦法,既能夠表示很小的數,又能表示很大數?

浮點數

就是浮點數(Floating Point),即float型別。

在一張便籤紙上,用一行來寫一個十進位制數,能夠寫下多大範圍的數?

要讓人能夠看清楚,所以字最小也有一個限制:紙張的寬度限制了我們能夠表示的數的大小。如果寬度只放得下8個數字,還是隻能寫下最大到99999999這樣的數字。

這裡的紙張寬度,和32個位元一樣,是在空間層面限制。現實怎麼表示一個大數?

如想要在一本科普書裡,寫宇宙內原子的數量,莫非是用一頁紙,用好多行寫下很多0?

不,我們會用科學計數法表示,如

1。0×10^82

,而非寫82個0。

計算機也可採用類似辦法,用科學計數法表示實數。浮點數的科學計數法的表示,有個IEEE標準,定義了兩個基本格式:

32位元表示單精度的浮點數,即float或float32型別

64位元表示雙精度的浮點數,也就是我們平時說的double或者float64型別

單精度的32位元可分成三部分。

第一部分,一個符號位,表示正數or負數。一般用s表示。在浮點數里,我們不像正數分符號數還是無符號數,所有的浮點數都是有符號。

8位元組成的指數位。一般用e表示。8位元能表示的整數空間,就是0~255。這裡用1~254對映到-126~127這254個有正有負的數上。

浮點數,不僅想要表示大數,還希望能夠表示很小的數,所以指數位也有負數。

沒有用到0和255。沒錯,這裡的 0(也就是8個位元全部為0) 和 255 (也就是8個位元全部為1)另有它用。

23位元組成的有效數位。用f來表示

科學計數法的浮點數表示:

(-1)^s×1。f×2^e(−1)

s

×1。

f

×2

e

這裡的浮點數,無法表示0。要表示0和一些特殊數,就要用上在e裡留下的0和255,這兩個其實是標記位。

e=0 f=0時,就把這個浮點數認為是0:

浮點數和定點數是如何被計算機儲存的?

如0。5的符號s應該是0,f應該是0,而e應該是-1,也就是

0。5= (-1)^0×1。0×2^{-1}=0。50。5=(−1)0×1。0×2−1=0。5,對應的浮點數表示,就是32個位元。

s=0,e = 2^{-1}

s

=0,

e

=2−1,需要注意,e表示從-126到127個,-1是其中的第126個數,這裡的e如果用整數表示,就是2^6+2^5+2^4+2^3+2^2+2^1=12626+25+24+23+22+21=126,1。f=1。01。

f

=1。0。

這樣的浮點數表示下,不考慮符號,浮點數能表示的最小數和最大數:

1。17×10^{-38}1。17×10−38

3。40×10^{38}3。40×1038

比前面的BCD編碼能夠表示的範圍大多了。

總結

這樣的表示方式下,浮點數能夠表示的資料範圍一下子大了很多。

因為這個數對應的小數點的位置“浮動”,才被稱為浮點數。隨指數位e值不同,小數點位置也在動。

對應的,前面的BCD編碼的實數,就是小數點固定在某一位的方式,我們也就把它稱為定點數。

為什麼0。3 + 0。6不能得到0。9?

因為,浮點數沒有辦法精確表示0。3、0。6和0。9。0。1~0。9這9個數,只有0。5能夠被精確地表示成二進位制的浮點數:s = 0、e = -1、f = 0。

而0。3、0。6、0。9,都只是近似表達。浮點數無論是表示還是計算其實都是近似計算。

Top