為什么我們代碼將浮點數、整數進行強制轉換,或打印輸出時會出精度損失,或出錯的情況?
想要搞明白這個問題,就需要了解一下整數、浮點數的存儲規則。
浮點數存儲規則
根據國際標準IEEE(電氣和電子工程協會)規定,任何一個浮點數NUM的二進制數可以寫為:
NUM = (-1) ^ S * M * 2 ^ E; (S表示符號,E表示階乘,M表示有效數字) ①當S為0時,表示一個正數;當S為1時,表示一個負數; ②M表示有效數字,1<= M <2; ③2^E表示指數比如十進制的3.0,二進制就是0011.0 就可以寫成(-1)^ 0 * 1.1 * 2 ^ 1 再比如十進制的-3.0,二進制就是-0011.0 就可以寫成(-1)^ 1 * 1.1 * 2 ^ 1 而規定float類型有一個符號位(S),有8個指數位(E),和23個有效數字位(M) double類型有一個符號位(S),有11個指數位(E),和52個有效數字位(M) 以float類型為例:
測試
代碼如下:void test(void)
{
float m=134.375;
char *a=(char*)&m;
printf("0x%p:%d ",a,*a);
printf("0x%p:%d ",a+1,*(a+1) );
printf("0x%p:%d ",a+2,*(a+2) );
printf("0x%p:%d ",a+3,*(a+3) );
}
代碼輸出結果:
具體的計算過程如下:
精度損失
我們可以把十進制的小數部分乘以2,取整數部分作為二進制的一位,剩余小數繼續乘以2,直至不存在剩余小數為止。例如0.2可以轉換為:0.2 x 2 = 0.4 00.4 x 2 = 0.8 00.8 x 2 = 1.6 10.6 x 2 = 1.2 10.2 x 2 = 0.4 00.4 x 2 = 0.8 00.8 x 2 = 1.6 1… 即:.0011001…它是一個無限循環的二進制數,這就是為什么十進制小數轉換成二進制小數的時候為什么會出現精度損失的情況。 之前前不久給大家分享的《單精度、雙精度、多精度和混合精度計算的區別是什么?》可能大家不是很明白,今天看了浮點數的存儲規則,你明白了嗎?整數的存儲規則
理解了浮點數的存儲規則,再理解整數就很簡單了。
整數在內存中都是以補碼的形式進行存儲,整數有正負之分。當需存儲有符號數時,用第一位來表示正(0)和負(1)。
正數的反碼和補碼還是它本身,下面主要討論下負數的反碼和補碼。反碼是其原碼除去最高符號位后其余位按位取反,補碼是其反碼在加上1 。
測試代碼:
輸出結果:void test(void)
{
int8_t n=-123;
uint8_t *p=(uint8_t *)&n;
printf("%d ",n);
printf("%d ",*p);
}

計算過程如下:
審核編輯 :李倩
-
二進制
+關注
關注
2文章
803瀏覽量
42154 -
浮點數
+關注
關注
0文章
61瀏覽量
16080 -
代碼
+關注
關注
30文章
4887瀏覽量
70259
原文標題:內存中整數和浮點數存儲的差異
文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
浮點數的表示方法

浮點數在內存中的存儲

什么是浮點數
FPGA浮點數表示及計算機數值表示規則

評論