欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言浮點(diǎn)型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)方式詳解

 更新時(shí)間:2023年03月30日 11:40:33   作者:CGod  
任何數(shù)據(jù)在內(nèi)存中都是以二進(jìn)制的形式存儲(chǔ)的,例如一個(gè)short型數(shù)據(jù)1156,其二進(jìn)制表示形式為00000100 10000100,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言浮點(diǎn)型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)方式,需要的朋友可以參考下

前言

深刻了解浮點(diǎn)型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)方式,是在修煉內(nèi)功,讓后續(xù)的學(xué)習(xí)更深刻,更容易發(fā)現(xiàn)編程過(guò)程中的問(wèn)題并解決問(wèn)題,繼續(xù)帶鐵汁們學(xué)一波干貨~沖!

一、思考一下

咱們先上一盤(pán)開(kāi)胃菜,試試看叭

#include<stdio.h>
int main()
{
	int n = 9;	 
	float* pFloat = (float*)&n;
	printf("n的值為:%d\n", n);
	printf("*pFloat的值為:%f\n", *pFloat);
	
	*pFloat = 9.0;
	printf("num的值為:%d\n", n);
	printf("*pFloat的值為:%f\n", *pFloat);	
	return 0;
}

路飛:請(qǐng)問(wèn)打印出來(lái)都是什么結(jié)果呢?貝吉塔:簡(jiǎn)單,喏

路飛:哈哈~雖然很符合直觀想法,但是錯(cuò)啦錯(cuò)啦,喏

貝吉塔:蛤??!這么奇怪的結(jié)果

二、浮點(diǎn)數(shù)存儲(chǔ)規(guī)則

既然上述結(jié)果跟我們所理解的整型數(shù)據(jù)存儲(chǔ)方式的結(jié)果不同,這就說(shuō)明浮點(diǎn)型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)方式是不一樣滴~

2.1 浮點(diǎn)數(shù)表示方法的規(guī)定

詳細(xì)解讀:

根據(jù)國(guó)際標(biāo)準(zhǔn)IEEE(電氣和電子工程協(xié)會(huì))754,任意一個(gè)二進(jìn)制浮點(diǎn)數(shù)V可以表示成下面的形式:

  • (-1)^S * M * 2^E
  • (-1)^S表示符號(hào)位。當(dāng)S=0,V為正數(shù);當(dāng)S=1,V為負(fù)數(shù)
  • M表示有效數(shù)字,大于等于1,小于2
  • 2^E表示指數(shù)位

舉例來(lái)說(shuō):

十進(jìn)制的5.5,寫(xiě)成二進(jìn)制是101.1,相當(dāng)于(1)^0 * 1.011 * 2^2,此時(shí)

aiphabetValue
S0
M1.011
E2

此時(shí)會(huì)有鐵汁有疑問(wèn),為什么5.5的二進(jìn)制是101.1??不應(yīng)該是101.101嗎?

我們看看下圖,假如是101.101,那么轉(zhuǎn)換成十進(jìn)制就是5.625,因?yàn)槎M(jìn)制每一位的權(quán)重都不同,不能想當(dāng)然

假如說(shuō)給的十進(jìn)制是5.3,那么這個(gè)0.3是不能精確表示的,所以說(shuō)浮點(diǎn)數(shù)容易丟失精度

2.2 浮點(diǎn)數(shù)的存儲(chǔ)

2.2.1 IEEE 754規(guī)定

對(duì)于32位的浮點(diǎn)數(shù)(float),最高的1位是符號(hào)位S,接著的8位是指數(shù)E,剩下的23位是有效數(shù)字M

對(duì)于64位的浮點(diǎn)數(shù)(double),最高的1位是符號(hào)位S,接著的11位是指數(shù)E,剩下的52位是有效數(shù)字M

2.2.2 IEEE 754對(duì)有效數(shù)字M,還有一些特別規(guī)定

前面說(shuō)過(guò),1≤M<2,也就是說(shuō),M可以攜程1.xxxxxx的形式。其中xxxxxx表示小數(shù)部分

IEEE 754規(guī)定,在計(jì)算機(jī)內(nèi)部保存M時(shí),默認(rèn)這個(gè)數(shù)的第一位總是1,因此可以被舍去,只保存后面的xxxxxx。比如保存1.01時(shí),只保存01,等到讀取的時(shí)候再放回去,這樣做的目的是節(jié)省空間

2.2.3 IEEE 754對(duì)指數(shù)E,還有一些特別規(guī)定

  1. 首先,E為一個(gè)無(wú)符號(hào)整數(shù)(unsigned int),這意味著,如果E為8位,它的取值范圍為0-255;如果E為11位,它的取值范圍為0-2047。
  2. 但是我們知道,科學(xué)計(jì)數(shù)法中的E是可以出現(xiàn)負(fù)數(shù)的,所以IEEE 754規(guī)定,存入內(nèi)存時(shí)E的真實(shí)值必須再加上一個(gè)中間數(shù)
  3. 對(duì)于8位的E,中間數(shù)取127;對(duì)于11位的E,中間數(shù)取1023。
  4. 比如2^10的E是10,所以保存成32位浮點(diǎn)數(shù)時(shí),必須保存成10+127=137,即為10001001

2.2.4 實(shí)操一下看看是怎樣存儲(chǔ)的

int main()
{
	float f = 5.5f;
	//(-1)^0 * 1.011 * 2^2
	//S = 0
	//M = 1.011
	//E = 2
	//這樣存: 0 10000001 01100000000000000000000
	//也就是: 0100 0000 1011 0000 0000 0000 0000 0000
	//十六進(jìn)制表示: 40 b0 00 00
	return 0;
}

5.5float存儲(chǔ),如圖所示

轉(zhuǎn)換成十六進(jìn)制就是40 b0 00 00,咱們調(diào)試看看叭~因?yàn)閂S是小端字節(jié)序存儲(chǔ),所以地址由低到高看到的是00 00 b0 40

2.3 浮點(diǎn)數(shù)從內(nèi)存中取出

2.3.1指數(shù)E從內(nèi)存中取出分三種情況

SM的取出很簡(jiǎn)單,原樣返回,但是E我就得仔細(xì)談?wù)劻?/p>

  • E不全為0或不全為1:

這時(shí),把E減去之前加上去的127(或1023),得到真實(shí)值,再講有效數(shù)字M前加上第一位的1,這種情況最簡(jiǎn)單,逆著來(lái)就是了

  • E為全0:

這時(shí)真實(shí)的E為-127(或-1023),太小了,所以規(guī)定浮點(diǎn)數(shù)的指數(shù)E等于1-127(或1-1023)即為真實(shí)值,有效數(shù)字M不再加上第一位的1,而是還原為0.xxxxxx的小數(shù)。這樣做是為了表示±0,以及接近于0的很小的數(shù)字(這是規(guī)定,大家不要糾結(jié))

  • E為全1:

這時(shí)真實(shí)的E128,太大了,如果有效數(shù)字M全為0,表示±無(wú)窮大(正負(fù)取決于符號(hào)位S)

2.3.2 實(shí)操一下看看是怎樣取出的

我們回到最開(kāi)始的代碼,看看能不能解決啦

#include<stdio.h>
int main()
{
	int n = 9;	 
	float* pFloat = (float*)&n;
	printf("n的值為:%d\n", n);
	printf("*pFloat的值為:%f\n", *pFloat);
	
	*pFloat = 9.0;
	printf("num的值為:%d\n", n);
	printf("*pFloat的值為:%f\n", *pFloat);	
	return 0;
}

答案:

  • 先分析前兩個(gè)輸出:

首先,9int類(lèi)型的,存儲(chǔ)按整型存儲(chǔ)規(guī)則,就是在內(nèi)存中都是以補(bǔ)碼形式存放的,而正數(shù)的原碼、反碼、補(bǔ)碼都一樣

int9
原碼00000000000000000000000000001001
反碼00000000000000000000000000001001
補(bǔ)碼00000000000000000000000000001001

2.第一個(gè)輸出是以%d(十進(jìn)制整型)輸出,所以輸出結(jié)果確實(shí)是9

3. 第二個(gè)輸出,pFloat指針認(rèn)為數(shù)據(jù)是以單精度浮點(diǎn)數(shù)類(lèi)型存儲(chǔ)的,所以解應(yīng)用的時(shí)候也是這么做的。此時(shí)pFloat發(fā)現(xiàn)E全為0,按照上述規(guī)則,9取出來(lái)就變成0.000000000000000000001001 * 2^-126,即使不管后面的指數(shù)!有效數(shù)字都已經(jīng)非常小了!所以打印出來(lái)小數(shù)點(diǎn)后6位看到的是0.000000

然后,分析后兩個(gè)輸出:

首先,9.0float類(lèi)型的,存儲(chǔ)按浮點(diǎn)數(shù)存儲(chǔ)規(guī)則,即為
(-1)^0 * 1.001 * 2^3

float9.0
S0
M1.001
E3

存到內(nèi)存里就是:

于是第三個(gè)輸出,%d把它當(dāng)整型輸出,那么在整型眼里,直接把這32位直接轉(zhuǎn)成十進(jìn)制輸出了,就造成了輸出結(jié)果為1091567616

而第四個(gè)輸出就是按float類(lèi)型輸出的,所以結(jié)果就是9.000000

三、總結(jié)

  • 內(nèi)存可以認(rèn)為都是一堆同樣的小格子
  • 但是整型和浮點(diǎn)型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)方式是不一樣的,哪怕都是一樣的內(nèi)存格子,卻有各自的規(guī)則限制著(看起來(lái)都是放格子里沒(méi)有差別)
  • 所以輸出的時(shí)候,也有取出的規(guī)則,不然都一樣了

到此這篇關(guān)于C語(yǔ)言浮點(diǎn)型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)方式的文章就介紹到這了,更多相關(guān)C語(yǔ)言浮點(diǎn)型數(shù)據(jù)在內(nèi)存的存儲(chǔ)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論