《深入理解電腦系統》閱讀筆記--信息的表示和處理(下)

来源:https://www.cnblogs.com/zhaof/archive/2018/06/05/9141986.html
-Advertisement-
Play Games

本應該之前整理好的,又拖到現在,不管怎麼樣繼續堅持看下去,從二章開始就越來越不好理解了 整數運算 再次來看之前的一個例子: 還是通過這裡例子來看這個部分的知識點 無符號加法 無符號加法原理: 其實每次看到這種原理推導過程自己基本都不怎麼願意去看,不過我們可以通過實際的例子來好好理解,來幫助自己更好的 ...


本應該之前整理好的,又拖到現在,不管怎麼樣繼續堅持看下去,從二章開始就越來越不好理解了

整數運算

再次來看之前的一個例子:

root@localhost: lldb
(lldb) print (500 * 400) * (300 * 200)
(int) $0 = -884901888
(lldb) print ((500 * 400)* 300) * 200
(int) $1 = -884901888
(lldb) print ((200 * 500) * 300) * 400
(int) $2 = -884901888
(lldb) print 400 * (200 * (300 * 500))
(int) $3 = -884901888
(lldb)

還是通過這裡例子來看這個部分的知識點

無符號加法

無符號加法原理:

其實每次看到這種原理推導過程自己基本都不怎麼願意去看,不過我們可以通過實際的例子來好好理解,來幫助自己更好的理解

通過一個確定的4位的無符號數來看,如果x = 9 y = 12 x和y的二進位表示分別為[1001] 和 [1100] 他們相加的和為21 這個時候其實超過了我們最開始設定的4位,需要用5位來表示也就是[10101] 如果我們丟掉了最高位,就成了[0101] 轉換為十進位就是5 其實這個值的計算結果就是21 對16 求餘 得到5是一致的
這個時候我們在來看上面的公式原理,其實就是當你兩個數相加已經超過了最大位數的時候,最高位就會被捨棄,即當結果溢時需要捨棄最高位的值

無符號求反

 還是先看原理:

這裡其實我自己有點小疑惑,因為剛開始的時候,我理解的無符號數求反,是把一個數的二進位表示方式求反得到的值,這樣吧,通過一個實際的例子來理解:
對於12 二進位為[1100] 我理解的求反得到的是[0011]這樣得到的數是3 

但是這裡講的無符號數求反,其實是通過2的4次方 減去 12 得到的是 4

所以這裡有點不確定,這個求反,後續再查資料看看是怎麼回事

補碼加法

這裡第一次看的時候沒有理解,不過後來又過了幾天再看了一下理解了(可能之前看的時候,一眼看去都是公式,自己就不想看)

既然是補碼的加班,先回顧一下補碼的最大值和最小值
對於一個w為的補碼數來說,能表示的最小值為:-2的w-1次方, 表示的最大值為:2的w-1次方 減1

在給定範圍x>=-2的w-1次方, y <= 2的w-1次方減1 它們的和的範圍就是-2的w次方<=x+y<=2的w次方減2

來吧,先看一下原理:

 

當x+y的值超過的補碼的最大值的時候即大於TMax的時候是正溢出,需要減去2的w次方
當x+y的值小於補碼的最小值的時候即小於Tmin的時候是負溢出,需要加上2的w次方

補碼的非

還是先看原理:

 

 其實對於補碼的非有個簡單的方法
先看幾個實際的例子:

總結為一句話就是:對每一位求補,在對其結果加1

其實還有一種方法,還是通過一些例子理解:

其實總結一下就是:找到最右邊的1,然後這個1的左邊的所有位進行取反

無符號乘法

無符號的最大值的表示是2的w次方減1,那麼對於x >=0 y <= 2的w次方減1,x和y的乘積的取值範圍就是0到 (2的w次方減1)的平方, 這樣可能就會需要2w位來表示,C語言中的無符號乘法被定義為產生w為的值,就是2w位的整數乘積的低w位表示的值
來看看原理為:

補碼乘法

還是先看原理:

 

其實對於無符號和補碼乘法來說乘法的位級運算都是一樣的

通過下麵這個實際的例子,就會更加清楚:

 

乘以2的冪

早些時候,在大多數機器上,整數的乘法指令是非常慢的,所以編譯器對此作了優化,通過位移和加法運算的組合方式來代替乘以常數因數的乘法

原理如下:

一般原理看起來都不容易理解,或者估計很多人和我剛開始看的時候一樣也是直接忽略,所以還是結合例子來看:
還是以w=4來看,即4位, 11可以通過二進位[1011]表示,k=2 時,將其左移到6位向量得到[101100],即編碼為無符號數11*4 = 44

 

無論是無符號運算還是補碼運算,乘以2的冪都可以能會導致溢出。但是即使溢出的時候,通過位移得到的結果也是一樣的

由於整數乘法比位移和加法的代價要大的多,許多c語言編譯器試圖以位移、加法和減法的組合來消除很多整數乘以常數的情況,一個例子:
x * 14 利用14 = 2的3次方 + 2的2次方 + 2的1次方 編譯器會講乘法重寫為(x<<3) + (x<<2) + (x<<1)
無論x是無符號還是補碼,甚至當乘法會導致溢出時,兩個計算都會得到一樣的結果
設置編譯器還可以利用14 = 2的4次方 - 2的1次方 將乘法重寫為(x<<4)-(x<<1)
下麵是一個例子:

 

中間的移位表示要有幾個移位,後面的加法/減法表示做幾次加法或者減法

除以2的冪

大多數機器上,整數除法要比整數乘法更慢,需要30個或者更多的時鐘周期

除以2的冪也可以用移位運算來實現,不過這裡用的是右移,而不是左移
無符號和補碼分別使用邏輯移位和算數移位來達到目的

來看原理:

 

下麵是在12340的16位表示上執行邏輯右移的結果對它執行邏輯右移的結果,以及對它執行除以1,2,16,和256的結果

當x>=0, 變數x的最高有效位為0,所以效果與邏輯右移是一樣的,因此對於非負數來說,算術右移k位,和除以2的k次方是一樣的
下圖是-12340的16位表示進行算術右移不同位數的結果。對於不需要舍入的情況結果是x/2的k次方
當時當需要進行舍入的時候,位移導致結果向下舍入入右移4位會把-771.25向下舍入為-772

關於除以2的冪的補碼除法,向上舍入不是非常理解,後面需要再看

 

在執行算術右移之前加上一個適當的偏執量來修正舍入,看下圖:

在第三列,給出了-12340加上偏量值之後的結果,低k位以斜體表示,可以看出,低k位左邊的位可能會加1,也可能不會加1,對於不需要舍入的情況k=1,加上偏量只會影響那些被移掉的位,對於需要舍入的情況,加上偏量導致較高的位加1,所以結果會向零舍入

關於整數運算的小結

電腦執行的整數運算實際上是一種模運算形式,表示數字的有限字長限制了可能的值的取值範圍,結果可能溢出。
同時補碼表示還提供了一種既能表示負數,也能表示正數的靈活方法,使用了與執行無符號算術相同的位級實現,包括:加法,減法,乘法,除法,無論運算是以無符號形式還是以補碼形式,都完全一樣活著非常類似的位級行為

浮點數

浮點數可以用統一的公式表示:

 

 

 如:

並且可以看到除以2 就相當於右移,並且可以橫跨小數點
當時這種表示是有問題的,如:x/2的k次方的數可以精確表示,其他數字會變成迴圈小數
如1/3 = 0.0101010101[01]....

IEEE浮點數標準

IEEE標準中,用下麵公式表示浮點數

 

符號(sign):s是符號位,決定正負
尾數(singificand):M是一個二進位小數,它的範圍通常是[1.0,2.0]
階碼(exponent):E 的作用是對浮點數加權,這個權重是2的E次冪

其中 s 對應著符號位,exp 對應著 E,frac 對應著 M。不同的位數就代表了不同的表示能力,也就是單精度,雙精度,擴展精度的來源。

規範化值

在 exp≠000…0 和 exp≠111…1 時,表示的其實都是規範化的值

再來看公式:

這裡的 E 是一個偏移的值 E=Exp−Bias
Exp: 是 exp 編碼區域的無符號數值
Bias:值為 2的k-1次方−1 的偏移量,其中 k 是 exp 編碼的位數,也就是說
單精度:127(Exp: 1…254, E: -126…127)
雙精度:1023(Exp: 1…2046, E: -1022…1023)
之所以需要採用一個偏移量,是為了保證 exp 編碼只需要以無符號數來處理。
而對於 M,一定是以 1 開頭的:也就是 M=1.xxx…x。其中 xxx 的部分就是 frac 的編碼部分,當 frac=000.00 的時候值最小(M=1.0),當 frac=111。。。1 的時候值最大(M=2.0−ϵ)

一個例子:
float F = 15213.0
用上面方法理解:
15213=11101101101101=1.1101101101101×2的13次方
於是 frac 部分的值就是小數點後面的數值,而 Exp = E + Bias = 13 + 127 = 140 = 10001100,於是編碼出來的浮點數是這樣的:

0 10001100 11011011011010000000000
s exp frac

非規範化值

當 exp=000…0 的時候,值是非規範化的,意思是,雖然實數軸上原來連續的值會被規範到有限的定值上,但是並些定值之間的間距也是一樣的

 

和前面不同的是
E=1−Bias

而且 M=0.xxx…x,不是以 1 開頭了。

當 exp=000…0 且 frac = 000…0 時,表示 0,而且因為符號位的緣故,實際上是有 +0 和 -0 兩種的。而在 exp=000..0 且 frac≠000…0 時,數值是接近 0 的,並且間距是一致的

特殊值

還有一種特殊情況,就是 exp=111…1 時,表示一些特殊值。

當 exp=111…1 且 frac = 000…0 時,表示 ∞,而且因為符號位的緣故,實際上是有 +∞ 和 −∞ 兩種的。那些會溢出的操作就會用這個來表示,比如 1.0/0.0=−1.0/0.0=+∞,1.0/−0.0=−∞
而在 exp=111…1 且 frac≠000…0 時,我們認為這不是一個數值(Not-a-Number,NaN),用來表示那些沒辦法確定的值,比如 sqrt(−1),∞−∞,∞×0

通過例子理解:

接下來舉一個實際的例子,我們採用 1 位符號位,4 位 exp 位,3 位 frac 位,因此對應的 bias 為 7。回顧一下幾個重要公式:

對於規範化數:E=Exp−Bias;對於非規範數:E=1−Bias,正數部分的數值為

 

    s exp  frac   E   值
------------------------------------------------------------------
    0 0000 000   -6   0   # 這部分是非規範化數值,下一部分是規範化值
    0 0000 001   -6   1/8 * 1/64 = 1/512 # 能表示的最接近零的值
    0 0000 010   -6   2/8 * 1/64 = 2/512 
    ...
    0 0000 110   -6   6/8 * 1/64 = 6/512
    0 0000 111   -6   7/8 * 1/64 = 7/512 # 能表示的最大非規範化值
------------------------------------------------------------------
    0 0001 000   -6   8/8 * 1/64 = 8/512 # 能表示的最小規範化值
    0 0001 001   -6   9/8 * 1/64 = 9/512
    ...
    0 0110 110   -1   14/8 * 1/2 = 14/16
    0 0110 111   -1   15/8 * 1/2 = 15/16 # 最接近且小於 1 的值
    0 0111 000    0   8/8 * 1 = 1
    0 0111 001    0   9/8 * 1 = 9/8      # 最接近且大於 1 的值
    0 0111 010    0   10/8 * 1 = 10/8
    ...
    0 1110 110    7   14/8 * 128 = 224
    0 1110 111    7   15/8 * 128 = 240   # 能表示的最大規範化值
------------------------------------------------------------------
    0 1111 000   n/a  無窮               # 特殊值

從上面可以看出:
在 exp=0000 時,也就是非規範化的情況,間距是一致的,都是 1/8

因為位數的限制,從零到一之間的數字只能以 1/8 為最小單位來表示,且相鄰數字間間距一樣

在規範化的部分,可以發現由於 exp 部分的不同,所以相鄰數字間的間隔也是不同的,比方說最接近 1 的數字是 15/16 和 9/8,分別相差 1/16 和 1/8,這也是由於 IEEE 浮點數表示法的公式決定的

舍入

對於浮點數的加法和乘法來說,我們可以先計算出準確值,然後轉換到合適的精度。在這個過程中,既可能會溢出,也可能需要舍入來滿足 frac 的精度。

在二進位中,我們舍入到最近的偶數,即如果出現在中間的情況,舍入之後最右邊的值要是偶數,對於十進位數,例子如下:

 

  原數值       舍入結果    原因
2.8949999      2.89    不到一半,正常四捨五入
2.8950001      2.90    超過一半,正常四捨五入
2.8950000      2.90    剛好在一半時,保證最後一位是偶數,所以向上舍入
2.8850000      2.88    剛好在一半時,保證最後一位是偶數,所以向下舍入

小結

電腦將信息編碼為位(比特),通常組織成位元組序列。不同的編碼方式用來表示整數,實數和字元串
大多數機器對整數使用補碼編碼,對於浮點數使用IEEE標準編碼

由於編碼的長度有限,電腦運算具有不同的屬性,當超過表示範圍時,有限長度能夠引出數值溢出。
當浮點數非常接近0.0 從而轉換為0時,也會下溢

整體上第二章花了很多時間看,但是其實對很多知識還是沒有做到完全理解,後面可以回過頭重新來看,可能那個時候會有新的理解,也能更加深刻

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這篇來看一下反射的使用吧!舉個例子! 舉例子,肯定需要一個類啦,先建一個學生例子類: 有三個屬性,Id,Name,Sex。一個欄位Status,還有一個方法Show. 嗯~,破費科特。 來看看反射的各個方法或屬性怎麼使用吧! 獲取類型的公用屬性的方法(GetProperties) 輸出結果為: 是不 ...
  • 用DataTables時併發訪問量較大,單個任務操作(獲取數據)時間較長。連接數過多的時候就出現InvalidOpertionException錯誤。知道哪裡有問題那就好辦了,對GetDataTable(string sql):DataTable方法用線程鎖 lock() ,這樣就不會出現上述問題。 ...
  • ASP.NET Core MVC中的Views是負責網頁顯示,將數據一併渲染至UI包含HTML、CSS等。並能痛過Razor語法在*.cshtml中寫渲染畫面的程式邏輯。本篇將介紹ASP.NET Core MVC的Views。 之前 ASP.NET Core 2 學習筆記(六)MVC 有稍微介紹到V ...
  • 預設情況下,在VisualStudio中開髮網站,會運行在IISExpress中,如果想把網站部署到本地的IIS伺服器上該怎麼辦呢? 一、首先,以管理員身份運行VisualStudio,否則在修改項目屬性時將彈出如下對話框,阻止我們修改伺服器為本地IIS。 然後,雙擊Properties圖標,打開W ...
  • Util是一個.net core平臺下的應用框架,旨在提升小型團隊的開發輸出能力。Util 自 NCC 創設之日起便已加入,作者低調朴素、持續更新,項目日趨成熟、追求完美,於 2018 年 5 月成為 NCC 第二個星數破千的項目,值得祝賀,特發此文。 ...
  • 關於Windows 的安裝光碟版本很多種,很多人不知道選擇哪些。 ...
  • 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 原文地址: https://www.cnblogs.com/poterliu/p/9142637.html 1 nginx安裝環境 nginx是C語言開發,建議在linux上運行,本教程使用Centos6.5作為安裝環境。 n gcc 安裝ngi ...
  • 一,獨立按鍵註意一下幾點 >按下的時候,電壓被拉低,所以IO口要傳低電平( 0x0 ) >按下的時候要消除抖動 ( 延時10ms ),在判斷,是否還是低電平,再做業務處理 下麵這段程式,就是通過一個獨立按鍵連接到p1口,控制靜態數位管的 一段 進行亮和滅的切換。 二, 當按鍵比較多的時候,用矩陣按鈕 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...