浮點數精度問題?比特(bit,binary digit的縮寫)中文翻譯為“二進位數字”、“二進位” 或簡稱為 “位”,我來為大家科普一下關于浮點數精度問題?以下内容希望對你有幫助!
比特(bit,binary digit的縮寫)中文翻譯為“二進位數字”、“二進位” 或簡稱為 “位”。
比特隻有 2 種取值:0和1,一般無大小之分。
如同DNA是人體組織的最小單位、原子是物質的最小組成單位一樣,比特是組成數字信息的最小單位。
數值、文字、符号、圖像、聲音、命令······都可以使用比特來表示。
2 比特的三種基本邏輯運算比特的取值“0”和“1” 可表示兩種不同的狀态(例如電位的高/低、開關的斷開/接通)。
比特的運算使用邏輯代數,它有3種基本邏輯運算:
邏輯加(也稱“或”運算,用符号“OR”、“∨”或“+”表示)。
邏輯乘(也稱“與”運算,用符号“AND”、 “∧”或“ · ”表示,也可省略)。
取反(也稱“非”運算,用符号“NOT”或上橫杠“¯”表示)。
兩個多位的二進制信息進行邏輯運算時,按位獨立進行,即每一位都不受其它位的影響:
例1
A:0110 ∨ B:1010 F: 1110
例2
A: 0110∧ B: 1010 F: 0010
3 比特在計算機中如何表示?表示一個比特需要使用兩個狀态:
電路的高電平狀态或低電平狀态(CPU)
電容的充電狀态或放電狀态(RAM)
兩種不同的磁化狀态(磁盤)
光盤面上的凹凸狀态(光盤)
···
4 比特的存儲存儲(記憶)1個比特需要使用具有兩種穩定狀态的元器件,例如:開關、燈泡等。
4.1 比特在CPU中的存儲
在計算機的CPU中,比特使用一種稱為“觸發器”的雙穩态電路來存儲。
觸發器有兩個狀态,可分别用來記憶0和1,1個觸發器可存儲1個比特。
一組(例如8個或16個)觸發器可以存儲1組比特,稱為“寄存器”。
CPU中有幾十個甚至上百個寄存器。
斷電後信息不再保持、為易失性存儲器!
4.2 比特在内存中的存儲
計算機存儲器中用電容器存儲二進位信息:當電容的兩極被加上電壓,它就被充電,電壓去掉後,充電狀态仍可保持一段時間,因而1個電容可用來存儲1個比特。
電容C處于充電狀态時,表示1
電容C處于放電狀态時,表示0
集成電路技術可以在半導體芯片上制作出以億計的微型電容器,從而構成了可存儲大量二進位信息的半導體存儲器芯片。
斷電後信息不再保持!
4.3 比特在外存儲器中的存儲
磁盤:利用磁介質表面區域的磁化狀态來存儲二進位信息。
光盤:隻讀光盤通過“刻”在光盤片表面上的微小凹坑來記錄二進位信息。
斷電後信息可以保持、為非易失性存儲器!
5 存儲容量的計量單位8個比特=1個字節(byte,用大寫B表示)
計算機内存儲器容量的計量單位:
KB: 1 KB=2^10字節=1024 B (千字節) MB: 1 MB=2^20字節=1024 KB(兆字節) GB: 1 GB=2^30字節=1024 MB(吉字節、千兆字節) TB: 1 TB=2^40字節=1024 GB(太字節、兆兆字節)
外存儲器容量經常使用10的幂次來計算:
1MB=10^3 KB =1 000 KB 1GB=10^6 KB =1 000 000 KB 1TB= 10^9 KB = 1 000 000 000 KB
不同進位制前綴的使用場合:
内存、cache、半導體存儲器芯片的容量均使用二進制前綴:
512MB的内存條( 1M=2^20 )
256KB 的cache(1K= 2^10 )
文件和文件夾的大小使用二進制前綴。
頻率、傳輸速率等使用十進制前綴:
主頻 1GHz(1G=10^9)
傳輸速率 100Mbps(1M=10有^6)
外存儲器(硬盤、DVD光盤、U盤、存儲卡等)容量:
廠商标注的容量使用十進制前綴。
操作系統顯示的容量使用二進制前綴。
6 比特的傳輸信息是可以傳輸的,信息隻有通過傳輸和交流才能發揮它的作用。
在數字通信技術中,信息的傳輸是通過比特的傳輸來實現的。
近距離傳輸時:直接将用于表示“0/1”的電信号或光信号進行傳輸(稱為基帶傳輸),例如:
計算機讀出或者寫入移動硬盤中的文件。
使用打印機打印某個文檔的内容。
遠距離傳輸或者無線傳輸時:需要使用調制技術。
比特的傳輸速率:
傳輸速率表示每秒鐘可傳輸的二進位數目,常用單位是:
比特/秒(b/s),也稱“bps”。如 2400 bps(2400b/s) 千比特/秒(kb/s),1kb/s=103比特/秒=1 000 b/s 兆比特/秒(Mb/s),1Mb/s=106比特/秒=1 000 kb/s 吉比特/秒(Gb/s),1Gb/s=109比特/秒=1 000 Mb/s 太比特/秒(Tb/s),1Tb/s=1012比特/秒=1 000 Gb/s
8 不同進位制數的表示和含義“數”是一種信息,它有大小(數值),可以進行四則運算。
“數”有不同的表示方法。日常生活中人們使用的是十進制數,但計算機使用的是二進制數,程序員還使用八進制和十六進制數,它們怎樣表示?其數值如何計算?
8.1 十進制數
每一位可使用十個不同數字表示(0、1、2、3、4、5、6、7、8、9)。
低位與高位的關系是:逢10進1。
各位的權值是10的整數次幂(基數是10 )。
标志: 尾部加“D”或缺省。
例:
204.96=2×10^2+0×10^1+4×10^0+9×10^-1+6×10^-2
8.2 二進制數
每一位使用兩個不同數字表示(0、1),即每一位使用 1 個“比特”表示。
低位與高位的關系是:逢2進1。
各位的權值是 2 的整數次幂(基數是2 )。
标志: 尾部加B
例:
101.01 B =1×2^2+0×2^1+1×2^0 +0×2^-1+1×2^-2 =5.25
8.3 十六進制數
用十六進制數來表示二進制數,相當于二進制數來說,更直觀,因為4個二進制位可以用1個十六進制位來表示,因為二進制的1111等于十進制的15,也就是十六進制的F。十進制與二進制的位數對位沒有十六進制方便,一位十進制相當于約3.2位二進制。
每一位使用十六個數字和符号表示(0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F )。
逢16進1, 基數為16。
各位的權值是16的整數次幂(基數是16 )。
标志:尾部加H。
例:
F5.4H=15×16^1 5×16^0 4×16^-1 = 245.25
8.4 八進制數
一位八進制數可以表示三位二進制數,因為二進制的111也就是八進制的7。
每一位使用八個不同數字表示(0、1、2、3、4、5、6、7)。
低位與高位的關系是:逢8進1。
各位的權值是8的整數次幂(基數是8 )。
标志:尾部加Q。
例:
365.2Q = 3×8^2 6×8^1 5×8^0 2×8^-1 = 245.25
9 不同進制數的相互轉換熟練掌握不同進制數相互之間的轉換,在編寫程序和設計數字邏輯電路時很有用。
隻要學會二進制數與十進制數之間的轉換,與八進制、十六進制數的轉換就不在話下了。
9.1 十進制數→二進制數
轉換方法:
整數和小數分開轉換。
整數部分:除以2逆序取餘
小數部分:乘以2順序取整
例如:29.6875→ 11101.1011 B
注意:十進制小數(如0.63)在轉換時會出現二進制無窮小數,這時隻能取近似值。
9.2 二進制數→十進制數
轉換方法:
二進制數的每一位乘以其相應的權值,然後累加即可得到它的十進制數值。
例: 11101.1011B
= 1×2^4+1×2^3+1×2^2+0×2^1+1×2^0
+1×2^-1+0×2^-2+1×2^-3+1×2^-4
= 29.6875
9.3 八進制數與二進制數的互換
八進制→二進制:把每個八進制數字改寫成等值的3位二進制數,且保持高低位的次序不變。
例: 2467.32Q → 010 100 110 111 . 011 010 B
二進制→八進制:整數部分從低位向高位每3位用一個等值的八進制數來替換,不足3位時在高位補0湊滿3位;小數部分從高位向低位每3位用一個等值八進制數來替換,不足3位時在低位補0湊滿三位。
例: 1 101 001 110.110 01 B → 001 101 001 110.110 010 B
→ 1516.62 Q
9.4 十六進制數與二進制數的互換
轉換方法:與八、二進制互換的方法類似。
例1:35A2.CFH → 11 0101 1010 0010.1100 1111B
例2:11 0100 1110.1100 11B → 34E.CCH
10 PC機中數的主要類型都采用二進制表示,有不同類型和不同長度。
不同類型和不同長度的數各有不同的用途。
10.1 無符号整數的表示
10.2 有符号整數的表示
負數的絕對值如何用補碼表示?
先表示為自然碼。
将自然碼的每一位取反碼。
在最低位加“1”。
如4個位的補碼方案可以表示的數據範圍:
10.3 原碼和補碼的優缺點分析
原碼表示法:
優點:與日常使用的十進制表示方法一緻,簡單直觀。
缺點:加法與減法運算規則不統一,增加了成本;整數0 有“00000000”和“10000000”兩種表示形式,不方便。
補碼表示法:
優點:加法與減法運算規則統一, 沒有“-0”,可表示的數比原碼多一個(-2n-1)。
缺點:不直觀,人使用不方便。
10.4 原碼和補碼可表示的整數範圍
原碼可表示的整數範圍:
8位原碼: - 27 1~27- 1(- 127~127)
16位原碼: - 215 1~215- 1(- 32767~32767)
n 位原碼: - 2n-1 1~2n-1- 1
補碼可表示的整數範圍:
8位補碼:- 27~27- 1 (- 128~127 )
n位補碼:- 2n-1~2n-1- 1
- 128表示為 10000000
127 表示為 01111111
10.5 整數在計算機中的表示的對比
計算機中整數有多種,同一個二進制代碼表示不同類型的整數時,其含義(數值)可能不同。
一個代碼它到底代表哪種整數(或其它東西),是由指令決定的。
10.6 實數的特點與表示方法
實數是既有整數部分又有小數部分,小數點位置不固定。
任何一個實數總可以表達成一個乘幂和一個純小數之積。
例如:
56.725 = 0.56725×10^2
-0.0034756 = -0.34756×10^-2
實數的表示方法(記階法/浮點表示法):用3個部分表示:
乘幂中的指數(也稱階碼):表示實數中小數點的位置。
純小數部分(尾數):表示實數中的有效數字部分。
數的正負(符号)。
二進制實數的浮點表示:
與十進制實數一樣,二進制實數也可以用記階法表示,如:
1001.011B = 0.1001011B×2^ 100
-0.0010101B = -0.10101B×2^-10
可見,任一個二進制實數 N 均可表示為:
N=±S×2P
(其中, ±是該數的符号; S是N 的尾數;P是N的階碼)
因此,32位的單精度浮點數在計算機中可表示為:
由于指數(階碼)可以選用不同的編碼(原碼、補碼等),尾數的格式和小數點位置也可以有不同的規定,因此早期計算機中浮點數的表示方法互不相同。
現代計算機中,一般都以IEEE 754标準存儲浮點數,這個标準的在内存中存儲的形式為:
對于不同長度的浮點數,階碼與小數位分配的數量不一樣,如對于32位的單精度浮點數,數符分配是1位,階碼分配了8位,尾數分配了是23位:
符号位:0表示正;1表示負;
偏移階碼e:e=指數的實際值 127。
假有一個浮點數10110010.001,則指數是7,階碼就要用7 127的二進制數表示,也就是:111 01111111 = 10000110
尾數使用原碼表示,絕對值在1與2之間,其中1和小數點都是隐含的,并不直接表示。
根據這個标準,我們來嘗試把一個十進制的浮點數轉換為IEEE754标準表示。
例如:178.125
先把浮點數分别把整數部分和小數部分轉換成2進制:
整數部分用除2取餘的方法,求得:10110010
小數部分用乘2取整的方法,求得:001
合起來即是:10110010.001
轉換成二進制的浮點數,即把小數點移動到整數位隻有1,即為:1.0110010001 * 2^111,111是二進制,由于左移了7位,所以是111
把浮點數轉換二進制後,這裡基本已經可以得出對應3部分的值了:
數符:由于浮點數是正數,故為0(負數為1)。
階碼 : 階碼的計算公式:階數 偏移量, 階碼是需要作移碼運算,在轉換出來的二進制數裡,階數是111(十進制為7),對于單精度的浮點數,偏移值為01111111(127)[偏移量的計算是:2^(e-1)-1, e為階碼的位數,即為8,因此偏移值是127],即:111 01111111 = 10000110
尾數:小數點後面的數,即0110010001
最終根據位置填到對位的位置上:
可能有個疑問:小數點前面的1去哪裡了?由于尾數部分是規格化表示的,最高位總是“1”,所以這是直接隐藏掉,同時也節省了1個位出來存儲小數,提高精度。
浮點數的二進制顯示可以使用以下代碼:
#include<iostream> #include <bitset> //STL的bitset模闆類 using namespace std; void main() { union { float input; int output; } data; data.input = 178.125; std::bitset<sizeof(float) * 8>bits2(data.output); //bitset模闆類定義對象,<>内為長度,()為值 //如bitset<8> bitset2(12); //長度為8,二進制保存,前面用0補充 std::cout << bits2 << std::endl; system("pause"); } //01000011001100100010000000000000
-End-
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!