浮點數在計算機中是如何表示?
電子計算機只能儲存0和1,人類世界所能認識的任何資料都需要透過轉換為二進位制再進行儲存。整數(int)型轉換為二進位制儲存很好理解,那麼float型資料計算機又是怎麼儲存的呢?常說的浮點型資料精度丟失和資料溢位又是怎麼回事呢?
位:來自英文bit,音譯為“位元”,表示二進位制位。位是計算機內部資料儲存的最小單位,11010100是一個8位二進位制數。
位元組:來自英文Byte,音譯為“拜特”,習慣上用大寫的“B”表示。位元組是計算機中資料處理的基本單位。計算機中以位元組為單位儲存和解釋資訊,規定一個位元組由八個二進位制位構成,即1個位元組等於8個位元(1Byte=8bit)。八位二進位制數最小為00000000,最大為11111111;通常1個位元組可以存入一個ASCII碼,2個位元組可以存放一個漢字國標碼。
int型資料根據平臺型別不同,所佔用位元組大小也不同,這裡就按正常的4個位元組來講。整型分有符號和無符號,有符號左邊最高位為符號位。
unsigned int和signed in按四個位元組計算,也就是4*8=32位。int預設是signed有符號位的。所以,unsigned int表示的範圍是:0~2的32次方-1。signed int表示的範圍是:-2的31次方~2的31次方-1。
例如+3,轉為二進位制是0000 0011,但是計算機是按補碼儲存整型資料的,正數的補碼就是其本身,但是負數的補碼就不是了。這裡不作細講,有興趣的朋友可以翻看我前面的文章,裡面有詳細介紹。
十進位制小數轉換成二進位制小數採用"乘2取整,按序取出"法。
整數部分按整數方式轉,用短除法,小數部分按如下方式,最後再用小數點合起來;
具體做法是:用2乘十進位制小數,可以得到積,將積的整數部分取出,再用2乘餘下的小數部分,又得到一個積,再將積的整數部分取出,如此進行,直到積中的小數部分為零,或者達到所要求的精度為止。然後把取出的整數部分按順序排列起來,先取的整數作為二進位制小數的高位有效位,後取的整數作為低位有效位。
例:0.734375轉二進位制,結果是0.101111。
0.734375 x 2 = 1.46875
0.46875 x 2 = 0.9375
0.9375 x 2 = 1.875
0.875 x 2 = 1.75
0.75 x 2 = 1.5
0.5 x 2 = 1.0
浮點數的儲存方式與整型資料不同。浮點數運算有自己的標準標準,也稱IEEE二進位制浮點數算術標準(IEEE 754),是20世紀80年代以來最廣泛使用的浮點數運算標準,為許多CPU與浮點運算器所採用。
根據國際標準IEEE(電氣和電子工程協會)規定,任何一個浮點數NUM的二進位制數可以寫為:NUM = (-1) ^ S * M * 2 ^ E;//(S表示符號,E表示階乘,M表示有效數字)
這個標準是什麼意思呢?其實說白了就是二進位制的科學計數法:
十進位制:12345678 = 1.2345678*10^7 ;
二進位制:例如十進位制11.0,寫成二進位制就是1011.0,用IEEE標準表示就是(-1)^0 × 1.011 × 2^3 ,s=0,M=1.011,E=3;
浮點數在記憶體中的儲存按下圖所示方式儲存:
1、對於S,用來表示符號,0為正,1為負
2、對於M:規定M在儲存時捨去第一個1,只儲存小數點之後的數字。這樣做節省了空間,以float型別為例,就可以儲存23位小數資訊,加上舍去的1就可以用23位來表示24個有效的資訊。
3、對於E(指數)E是一個位元組(8位)整數所以E的取值範圍為(0~ 255),但是在計數中指數是可以為負的,所以規定在存入E時,在它原本的值上加上中間數(127),在使用時減去中間數(127),這樣E的真正取值範圍就成了(-127~128)。
因此對於32為單精度浮點數:在IEEE-754標準中,32位浮點數X的真值可表示為:
X = (-1)^S×(1.M)×2 ^(E-127);
瞭解了float型資料的儲存原理,接下來了解一下float精度丟失的原因,以浮點數2.7為例:
首先,十進位制轉換成二進位制。由於2.7無法用二進位制精確表示,因此此處出現一次精度丟失。
2.7 => 10.10110011001…
然後,用IEEE標準表示二進位制浮點數,得到s=0,M=1.010110011001…,E=1。
10.1011001… => (-1)^0 × 1.01011001… × 2^1
最後,按照IEEE標準儲存資料。此時是單精度浮點數,M只能儲存小數點後23位,多餘的部分被丟棄了,因此此處又一次精度丟失。
既然儲存有位數限制,那麼溢位就很好理解了。超過最大能表示的數就是上溢,超過最小能表示的數就是下溢,只要計算出最大和最小能表示的數十多大就可以得出上下溢位的極限:
上溢極限:
下溢極限:
浮點數在計算機中是如何表示?
電子計算機只能儲存0和1,人類世界所能認識的任何資料都需要透過轉換為二進位制再進行儲存。整數(int)型轉換為二進位制儲存很好理解,那麼float型資料計算機又是怎麼儲存的呢?常說的浮點型資料精度丟失和資料溢位又是怎麼回事呢?
位和位元組位:來自英文bit,音譯為“位元”,表示二進位制位。位是計算機內部資料儲存的最小單位,11010100是一個8位二進位制數。
位元組:來自英文Byte,音譯為“拜特”,習慣上用大寫的“B”表示。位元組是計算機中資料處理的基本單位。計算機中以位元組為單位儲存和解釋資訊,規定一個位元組由八個二進位制位構成,即1個位元組等於8個位元(1Byte=8bit)。八位二進位制數最小為00000000,最大為11111111;通常1個位元組可以存入一個ASCII碼,2個位元組可以存放一個漢字國標碼。
int型資料儲存int型資料根據平臺型別不同,所佔用位元組大小也不同,這裡就按正常的4個位元組來講。整型分有符號和無符號,有符號左邊最高位為符號位。
unsigned int和signed in按四個位元組計算,也就是4*8=32位。int預設是signed有符號位的。所以,unsigned int表示的範圍是:0~2的32次方-1。signed int表示的範圍是:-2的31次方~2的31次方-1。
例如+3,轉為二進位制是0000 0011,但是計算機是按補碼儲存整型資料的,正數的補碼就是其本身,但是負數的補碼就不是了。這裡不作細講,有興趣的朋友可以翻看我前面的文章,裡面有詳細介紹。
float型資料儲存浮點數轉二進位制方法十進位制小數轉換成二進位制小數採用"乘2取整,按序取出"法。
整數部分按整數方式轉,用短除法,小數部分按如下方式,最後再用小數點合起來;
具體做法是:用2乘十進位制小數,可以得到積,將積的整數部分取出,再用2乘餘下的小數部分,又得到一個積,再將積的整數部分取出,如此進行,直到積中的小數部分為零,或者達到所要求的精度為止。然後把取出的整數部分按順序排列起來,先取的整數作為二進位制小數的高位有效位,後取的整數作為低位有效位。
例:0.734375轉二進位制,結果是0.101111。
0.734375 x 2 = 1.46875
0.46875 x 2 = 0.9375
0.9375 x 2 = 1.875
0.875 x 2 = 1.75
0.75 x 2 = 1.5
0.5 x 2 = 1.0
IEEE二進位制浮點數算術標準浮點數的儲存方式與整型資料不同。浮點數運算有自己的標準標準,也稱IEEE二進位制浮點數算術標準(IEEE 754),是20世紀80年代以來最廣泛使用的浮點數運算標準,為許多CPU與浮點運算器所採用。
根據國際標準IEEE(電氣和電子工程協會)規定,任何一個浮點數NUM的二進位制數可以寫為:NUM = (-1) ^ S * M * 2 ^ E;//(S表示符號,E表示階乘,M表示有效數字)
這個標準是什麼意思呢?其實說白了就是二進位制的科學計數法:
十進位制:12345678 = 1.2345678*10^7 ;
二進位制:例如十進位制11.0,寫成二進位制就是1011.0,用IEEE標準表示就是(-1)^0 × 1.011 × 2^3 ,s=0,M=1.011,E=3;
浮點數儲存浮點數在記憶體中的儲存按下圖所示方式儲存:
1、對於S,用來表示符號,0為正,1為負
2、對於M:規定M在儲存時捨去第一個1,只儲存小數點之後的數字。這樣做節省了空間,以float型別為例,就可以儲存23位小數資訊,加上舍去的1就可以用23位來表示24個有效的資訊。
3、對於E(指數)E是一個位元組(8位)整數所以E的取值範圍為(0~ 255),但是在計數中指數是可以為負的,所以規定在存入E時,在它原本的值上加上中間數(127),在使用時減去中間數(127),這樣E的真正取值範圍就成了(-127~128)。
因此對於32為單精度浮點數:在IEEE-754標準中,32位浮點數X的真值可表示為:
X = (-1)^S×(1.M)×2 ^(E-127);
精度丟失瞭解了float型資料的儲存原理,接下來了解一下float精度丟失的原因,以浮點數2.7為例:
首先,十進位制轉換成二進位制。由於2.7無法用二進位制精確表示,因此此處出現一次精度丟失。
2.7 => 10.10110011001…
然後,用IEEE標準表示二進位制浮點數,得到s=0,M=1.010110011001…,E=1。
10.1011001… => (-1)^0 × 1.01011001… × 2^1
最後,按照IEEE標準儲存資料。此時是單精度浮點數,M只能儲存小數點後23位,多餘的部分被丟棄了,因此此處又一次精度丟失。
溢位既然儲存有位數限制,那麼溢位就很好理解了。超過最大能表示的數就是上溢,超過最小能表示的數就是下溢,只要計算出最大和最小能表示的數十多大就可以得出上下溢位的極限:
上溢極限:
下溢極限: