亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

蟲蟲首頁| 資源下載| 資源專輯| 精品軟件
登錄| 注冊

您現在的位置是:首頁 > 技術閱讀 >  計算機不都是0101嗎,你有想過計算機是怎么表示的小數嗎?

計算機不都是0101嗎,你有想過計算機是怎么表示的小數嗎?

時間:2024-02-13


浮點數的計算機表示(IEEE 754),由 UCB 數學教授 William Kahan 主要起草。后者也因其卓越貢獻于1989年獲得圖靈獎。計算機組成原理與匯編語言這兩門課均對該內容有所講解。與課程中直接拋出公式與概念不同,我想首先與各位探討"科學計數法"這個概念,進而討論設計二進制的科學計數法需要涉及到哪些元素。接著,我們討論如何在內存上表達這個方案。最后討論計算機的具體實現。

科學計數法

我們都了解科學計數法。科學計數法的精妙之處在于,其將"量級"與"數值"兩個信息拆分,讓使用者對這兩個信息更加明確。

如上,我們可以將任何有理數拆分成的形式。值得注意的是:

  • 的取值范圍是
  • 一定是一個整數

對于任何有理數,我們都可以用兩個范圍狹小(規則明確)的數字 B 與 C 來表示。

此外,我們知道,十進制只不過是記錄數字大小的一種方式而已。歷史上出現過的二進制、三進制、二十進制,都可以毫無障礙地表示數字,并且還有其獨具的數學特性。

那么,二進制可以用科學計數法表示嗎?答案當然是肯定的。

二進制的科學計數法

注意,這里下標2,代表這個數是二進制。 同理,對應十進制中的數字

通過觀察十進制的科學計數法形式,對于二進制,我們自然可以做出如下約定:

  • 的取值范圍是
  • 一定是一個整數

這里我們補充說明一下,二進制的小數是什么樣的。對于 這個十進制數,如果要將其轉換為二進制:

  • 將其整數部分與小樹部分分開;
  • 對于整數部分 5 ,我們使用"不斷除以2取余數"的方法,得到 101 ;
  • 對于小數部分 .25 ,我們使用"不斷乘以2取整數"的方法,得到 .01

關于進制轉換的具體方法與背后的數學原理,我寫過一篇文章進行討論,見這里:十進制轉二進制 / 八進制 / 十六進制的手算方法,及其數學原理的通俗解釋

這里,我們只需要明確,二進制是存在小數形式的,且可以表示一切十進制可表示的數(的近似)。

計算機如何記錄二進制的科學計數法

接著,我們步入正題:只會表示0/1的計算機,如何記錄并表達浮點數呢?

給一個32位的空間,如果不做任何約束,我們只能將其理解為一個整數,并且其取值范圍為

這是因為,計算機只能記錄 0 和 1 這兩個信息,并不能直接記錄小數點點在哪里。因此,我們需要設置一定規則,取出一定位,用于表示小數點點在哪里。這必將犧牲一定的精度與取值范圍。

因此,我們將這 32 位空間分為三部分:

  • 第一部分,用于表示精度,即這個數字值是多少,對應上面的B;
  • 第二部分,用于表示小數點,即量級,對應上面的C;
  • 第三部分,用于表示正負,只需要使用1位。

在 IEEE 754 中,我們分別將上述一、二、三部分叫做尾數M階碼E符號s于是我們有了二進制的表達式:

為了表示盡可能多的、常用的小數,我們有如下需求

  • 對于符號位 s ,如果該位上是 0 ,則為正數;為 1 ,則為負數。
  • 對于尾數 M ,其取值范圍為
  • 對于階碼 E ,其為一個整數,并且取值范圍應該包含負數、0、正數。

可以注意到,對于 M 、 E ,我們并不能直接用二進制表示,還需要設定一定規則。

尾數 M

假設尾數 M 一共有 f 位,則 f 可表示的整數取值范圍為 ,我們稱 f 直接對應的非負整數為 C 。為了將其投影到 ,我們做出如下變換:

解碼 E

假設解碼 E 一共有 e 位,則 e 可表示的整數取值范圍為 ,我們稱 e 直接對應的非負整數為 Exp 。我們希望 E 可以取到負數,因此做出如下變換:

這樣,我們的 E 取值范圍就來到了

總結

有了如上設計的規則,我們便知曉了計算機記錄浮點數的方式,以及轉換流程。以下圖為例。

二進制轉換到其對應的十進制數0.15625過程

知識點與例題

上面我們討論了 IEEE 754 的思想,但是并不嚴謹,比如:

  • 正負無窮該怎么表達?
  • 如此表示會不會造成空間的浪費?
  • ...

因此,我們從數學上嚴謹地討論一道例題,考慮一下規格化浮點數。例題源自我的匯編語言筆記。

題目

給定一個浮點格式(IEEE 754),有k位指數和n位小數,對于下列數,寫出階碼E、尾數M、小數f和值V的公式。另外,請描述其位表示。

  • 數5.0;
  • 能夠被準確描述的最大奇數;
  • 最小的正規格化數。

解決

前置知識一:IEEE 754

IEEE 754約定,計算機中浮點數二進制表示為:

數字形式:

  • 符號:s
  • 尾數:M,是一個位于區間[1.0, 2.0)內的小數
  • 階碼:E

編碼形式:

sexpfrac

exp域:E(注意,E要進行變換,再存儲在exp中); frac域:M。

前置知識二:規格化浮點數(Normalized)

這里討論到規格化浮點數(Normalized):

  • 滿足條件:exp不全為0且不全為1。
  • 真實的階碼值需要減去一個偏置(biased)量:
    • 單精度數:127(Exp:1...254,E:-126...127)
    • 雙精度數:1023(Exp:1...2046,E:-1022...1023)
    • ,e = exp的域的位數
    • E = Exp - Bias
    • Exp:exp域所表示的無符號數值
    • Bias的取值:
  • frac的第一位隱含1:M = 1.xxx...x_2
    • 因此第一位的“1”可以省去,xxx...x:bits of frac
    • Minimum when 000...0 ()
    • Maximum when 111...1 ()
前置工作一:整理變量關系

則E為

E最大值為。(為什么不是呢?因為有規定:exp全部取1為“非規格化浮點數”,因此規格化浮點數中exp不能全部取1,頂多為(1)*(0)

E的最小值為。(為什么不是呢?因為有規定:exp全部取0為“非規格化浮點數”,因此規格化浮點數中exp不能全部取0,頂多為(0)*(1)

前置工作二:總結特性

拋開例題,來看一個例子:

  • 8位浮點數表示:exp域寬度為4 bits,frac域寬度為3 bits。則,其偏置量的值為2^(4-1) - 1 = 7.
  • 其他規則符合IEEE 754規范。

取值范圍如下表。

sexpfracEvalue
00000000-60
00000001-61/8 * 1/64 = 1/512
00000010-62/8 * 1/64 = 2/512

...


00000110-66/8 * 1/64 = 6/512
00000111-67/8 * 1/64 = 7/512
00001000-68/8 * 1/64 = 8/512
00001001-69/8 * 1/64 = 9/512

...


00110110-114/8 * 1/2 = 14/16
00110111-115/8 * 1/2 = 15/16
0011100008/8 * 1 = 1
0011100109/8 * 1 = 9/8
00111010010/8 * 1 = 10/8

...


01110110714/8 * 128 = 224
01110111715/8 * 128 = 240
01111000n/ainf

可以看出,假設frac有f位,則M可視為:

其中,C是整數,由frac決定,即

并且C滿足

則浮點數V的十進制即為:

也可寫作

其中,分別為exp、frac位數,為常數。

解決問題一:數0.5

較為簡單,直接解決如下。

0.5   // 轉換為二進制 ==>
0.1   // 移動小數點,使其在最左邊的1之后
M  = 1.0 // 小數點后的數字存儲在frac中
E = -1 // 因為是左移
frac= 0// 共n位
exp = E + Bias
 = -1 + (2^(e-1) - 1)

則,位的描述為:

sexpfrac
0bin(-1 + (2^(e-1) - 1))00....(共n位)
解決問題二:能夠被準確描述的最大奇數

根據前置工作二,可以看出,對于規格化浮點數可化簡為:

現在的任務有兩個:

  • 是整數,不能有小數(則應大于等于);
  • 是奇數(不是奇數,因此使為奇數,則取1,則取)。

下面分類討論:

情況一:E可以取到f時,

時,

取其能取的最大奇數,對應的二進制為: exp:dec2bin(),frac:1*(frac全為1)

情況二:E取不到f時,

這種情況不可能,因為E取不到f,則很多整數都不能表示。

解決問題三:最小的正規格化數

觀察:

分別取最小。

由前置工作一,,對應的二進制為: exp:0*1,frac:0*

后記:我第一學習浮點數是在2019年年末,當時對于浮點數的筆記和理解是有問題的。在此感謝一位湖南大學的朋友(公眾號 / CSDN:梓酥),給我發郵件,指出我的問題~

往期推薦






主站蜘蛛池模板: 福泉市| 庐江县| 洪洞县| 元氏县| 高安市| 三河市| 囊谦县| 黄浦区| 英吉沙县| 繁峙县| 湛江市| 凤凰县| 甘泉县| 五大连池市| 长乐市| 邓州市| 甘南县| 土默特右旗| 定日县| 宁强县| 望谟县| 常熟市| 大足县| 柯坪县| 都安| 和田市| 普安县| 航空| 天峻县| 安新县| 梧州市| 三门县| 沐川县| 华容县| 青州市| 唐山市| 安岳县| 高密市| 陈巴尔虎旗| 江西省| 安化县|