真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

”神仙修煉“之C的數(shù)據(jù)存儲(chǔ)-創(chuàng)新互聯(lián)

一、內(nèi)功之?dāng)?shù)據(jù)在內(nèi)存中的存儲(chǔ)
本章內(nèi)容重點(diǎn):
1.數(shù)據(jù)類型的不同類型
2.整型在內(nèi)存中的存儲(chǔ)方式
3.大小端字節(jié)序存儲(chǔ)
4.浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)方式
1.不同數(shù)據(jù)類型的介紹

我們先前已經(jīng)了解到的基本類型(內(nèi)置類型)如:

成都創(chuàng)新互聯(lián)是一家專注于成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)與策劃設(shè)計(jì),漠河網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:漠河等地區(qū)。漠河做網(wǎng)站價(jià)格咨詢:18980820575
char    //字符型,所占存儲(chǔ)空間為1字節(jié)
int     //基本整形,所占存儲(chǔ)空間為4字節(jié)
unsigned int     //無符號(hào)整型,所占存儲(chǔ)空間為4字節(jié)
long (int)       //長(zhǎng)整型,所占存儲(chǔ)空間為4/8字節(jié)
unsigned long    //無符號(hào)長(zhǎng)整型,所占存儲(chǔ)空間為4/8字節(jié)
long long (int)  //長(zhǎng)長(zhǎng)整型,所占存儲(chǔ)空間為8字節(jié)
short (int)      //短整型,所占存儲(chǔ)空間為2字節(jié)
unsigned short   //無符號(hào)短整型,所占存儲(chǔ)空間為2字節(jié)
float            //單精度浮點(diǎn)型,所占存儲(chǔ)空間為4字節(jié)
double           //雙精度浮點(diǎn)型,所占存儲(chǔ)空間為8字節(jié)
long double      //長(zhǎng)雙精度浮點(diǎn)型

類型存在的意義:

1.使用不同數(shù)據(jù)類型為內(nèi)存開辟不同的空間大小

2.不同數(shù)據(jù)所能表示的取值范圍不同,可以參與的運(yùn)算也不同

1.1🌜數(shù)據(jù)類型的分類🌛
    • 整型家族👪
char-----unsigned char
signed char
short----unsigned short
signed short
int-------unsigned int
signed int
long-----unsigned long
signed long
為什么char也在整型家族呢?
因?yàn)樽址且訟SCII存儲(chǔ)在內(nèi)存中,ASCLII是整數(shù),所以char屬于整型合情合理 👀(解決某些人的小疑問)。但是這里要注意 ?:在我們編程過程中,char具體表示的是signed char還是unsigned char是要根據(jù)編譯器決定的,常見的編譯器認(rèn)為char 是signed char。
    • 浮點(diǎn)數(shù)家族👪
float
double
    • 構(gòu)造類型(自定義類型)👪
數(shù)組類型(因?yàn)閿?shù)組元素個(gè)數(shù)可以發(fā)生改變)
結(jié)構(gòu)體類型struct
枚舉類型enum
共用體(聯(lián)合)類型union
    • 指針類型👪
int* pa
char* pb
float* pc
void *pd
    • 空類型👪
void表示空類型(無類型)
通常用于函數(shù)的返回類型,函數(shù)的參數(shù),指針類型。

2.🌜整型在內(nèi)存中的存儲(chǔ)🌛

由于一個(gè)變量在內(nèi)存中存儲(chǔ)需要開辟內(nèi)存的存儲(chǔ)單元,而不同的類型所開辟的空間大小有所不同,那么接下深刻理解一下整型 數(shù)據(jù)在內(nèi)存中的存儲(chǔ)👀

首先,我們要提前具備以下知識(shí)點(diǎn):

有符號(hào)整數(shù)和無符號(hào)整數(shù)
整數(shù)的原碼、反碼、補(bǔ)碼
2.1有符號(hào)整型和無符號(hào)整型(從二進(jìn)制來看)

有符號(hào)整數(shù)和無符號(hào)整數(shù)的區(qū)別在于如何理解整數(shù)最高位

  1. 對(duì)于無符號(hào)整數(shù):整數(shù)的最高位被編譯器理解為數(shù)據(jù)位。

  1. 對(duì)于有符號(hào)整數(shù):整數(shù)的最高位被編譯器理解為符號(hào)位。若最高位(符號(hào)位)為0則表示正數(shù),若符號(hào)位為1則表示負(fù)數(shù)。

  1. 可見對(duì)于相同字節(jié)數(shù)的整型數(shù)而言:由于有符號(hào)整數(shù)的數(shù)據(jù)位數(shù)比無符號(hào)整數(shù)的數(shù)據(jù)位數(shù)少1位,而這1位恰好是最高位,因此有符號(hào)整數(shù)表示的大整數(shù)的絕對(duì)值只有無符號(hào)整數(shù)的一半

//舉個(gè)栗子:我們可以查到char(signed char)和unsigned char的取值范圍
//char占1個(gè)字節(jié)
char--->-128~127
unsigned char--->0~255

在內(nèi)存中的存儲(chǔ)形式如上圖

2.2整數(shù)的原碼、反碼和補(bǔ)碼

計(jì)算機(jī)中整數(shù)的三種表示方法:原碼、反碼和補(bǔ)碼。三種方法都存在符號(hào)位和數(shù)據(jù)位之分。

由于正數(shù)的原碼反碼補(bǔ)碼相同,而負(fù)數(shù)的原碼反碼補(bǔ)碼不同,規(guī)則如下:

原碼:將二進(jìn)制按照正負(fù)數(shù)直接翻譯即可
反碼:原碼的符號(hào)位不變,其他位依次按位取反
補(bǔ)碼:在反碼的基礎(chǔ)上+1得到補(bǔ)碼
注意:
1.通過對(duì)補(bǔ)碼按“符號(hào)位不變,其他位依次取反”后“+1”可得到原碼。
2.同樣,對(duì)補(bǔ)碼先“-1”后,再“符號(hào)位不變,其他位依次取反”可得到原碼。
//例如:
int a=20;
//20是正數(shù),最高位是符號(hào)位0,整形占四個(gè)字節(jié)32個(gè)比特位
//正數(shù)的原碼反碼補(bǔ)碼:0000 0000 0000 0000 0000 0000 0001 0100
//轉(zhuǎn)換為十六進(jìn)制:0x 00 00 00 16
int b=-10;
//-10是負(fù)數(shù),最高位是符號(hào)位1
//原碼:1000 0000 0000 0000 0000 0000 0000 1010
//反碼:1111 1111 1111 1111 1111 1111 1111 0101
//補(bǔ)碼:1111 1111 1111 1111 1111 1111 1111 0110
//轉(zhuǎn)換為十六進(jìn)制:0xff ff ff f6

對(duì)于整型而言:在屏幕上顯示的是該數(shù)的原碼,在內(nèi)存中存儲(chǔ)的是該數(shù)的補(bǔ)碼,這是為什么呢?😧

在計(jì)算機(jī)系統(tǒng)中,數(shù)值一律用補(bǔ)碼來表示和存儲(chǔ)。原因在于,使用補(bǔ)碼,可以將符號(hào)位和數(shù)值域統(tǒng)
一處理;
同時(shí), 加法和減法也可以統(tǒng)一處理( CPU只有加法器)此外,補(bǔ)碼與原碼相互轉(zhuǎn)換,其運(yùn)算過程
是相同的,不需要額外的硬件電路。
//舉個(gè)栗子解釋一下:當(dāng)我們計(jì)算2-1的時(shí)候【相當(dāng)于2+(-1)】
2
//由于正數(shù)的原碼、反碼、補(bǔ)碼相同:
0000 0000 0000 0000 0000 0000 0000 0010
-1
//32位機(jī)器上-1的原碼:由于是負(fù)數(shù),最高位為符號(hào)位1
1000 0000 0000 0000 0000 0000 0000 0001
//-1的反碼:原碼符號(hào)位不變,其他位按位依次取反
1111 1111 1111 1111 1111 1111 1111 1110
//-1的補(bǔ)碼:反碼+1
1111 1111 1111 1111 1111 1111 1111 1111
2-1//相當(dāng)于2+(-1):如果不使用補(bǔ)碼,用原碼計(jì)算
0000 0000 0000 0000 0000 0000 0000 0010
1000 0000 0000 0000 0000 0000 0000 0001
//
1000 0000 0000 0000 0000 0000 0000 0011
//得出結(jié)果:-3,可見2-1=-3是錯(cuò)誤的

//當(dāng)我們使用-1的補(bǔ)碼計(jì)算的時(shí)候
0000 0000 0000 0000 0000 0000 0000 0010
1111 1111 1111 1111 1111 1111 1111 1111
//得出結(jié)果:1 0000 0000 0000 0000 0000 0000 0000 0000 0001
//由于只有32位,最前面的1舍掉得出:0000 0000 0000 0000 0000 0000 0000 0000 0001
//也就是1,2-1=1結(jié)果是正確的

通過在計(jì)算機(jī)內(nèi)存中負(fù)數(shù)用補(bǔ)碼來表示,就可以將減法運(yùn)算也轉(zhuǎn)化為加法運(yùn)算來處理。😁

2.3?大小端字節(jié)序存儲(chǔ)?

在了解大小端存儲(chǔ)之前,我們看一下在VS編譯器中數(shù)據(jù)在內(nèi)存中存儲(chǔ)是什么樣子的?

在VS編譯器中:按住Ctrl+F10進(jìn)行調(diào)試,打開軟件上面調(diào)試選項(xiàng),點(diǎn)擊窗口下的內(nèi)存即可打開
int a=20;
//20的原碼、反碼、補(bǔ)碼都相同:
//0000 0000 0000 0000 0000 0000 0001 0100 
int b=-10;
//-10是負(fù)數(shù)
//原碼:1000 0000 0000 0000 0000 0000 0000 1010
//反碼:符號(hào)位不變,其他位依次按位取反
//反碼:1111 1111 1111 1111 1111 1111 1111 0101
//補(bǔ)碼:反碼+1
//補(bǔ)碼:1111 1111 1111 1111 1111 1111 1111 0110
在內(nèi)存中是以十六進(jìn)制顯示的(二進(jìn)制和十六進(jìn)制的轉(zhuǎn)換)
//20以十六進(jìn)制顯示:00 00 00 14
//-10以十六進(jìn)制顯示:ff ff ff f6 
//在內(nèi)存中以補(bǔ)碼形式存儲(chǔ)數(shù)據(jù)

為什么在內(nèi)存中存儲(chǔ)方式和圖片顯示不符合呢?接下來正式引入功法!💣

1.什么是大端小端?
大端字節(jié)序存儲(chǔ)模式:數(shù)據(jù)的低位保存在內(nèi)存的高地址處,數(shù)據(jù)的高位保存在內(nèi)存的低地址處。
小端字節(jié)序存儲(chǔ)模式:數(shù)據(jù)的低位保存在內(nèi)存的低地址處,數(shù)據(jù)的高位保存在內(nèi)存的高地址處。
2.為什么有大端小端存儲(chǔ)呢?
為什么會(huì)有大小端模式之分呢?這是因?yàn)樵谟?jì)算機(jī)系統(tǒng)中,我們是以字節(jié)為單位的,每個(gè)地址單元
都對(duì)應(yīng)著一個(gè)字節(jié),一個(gè)字節(jié)為8bit。但是在C語言中除了8 bit的char之外,還有16 bit的short型,32 bit的long型(要看具體的編譯器),另外,對(duì)于位數(shù)大于8位
的處理器,例如 16位或者32位的處理器,由于寄存器寬度大于一個(gè)字節(jié),那么必然存在著一個(gè)如
何將多個(gè)字節(jié)安排的問題。因此就導(dǎo)致了大端存儲(chǔ)模式和小端存儲(chǔ)模式。
例如:一個(gè) 16bit 的 short 型 x ,在內(nèi)存中的地址為 0x0010 , x 的值為 0x1122 ,那么 0x11 為
高字節(jié), 0x22 為低字節(jié)。對(duì)于大端模式,就將 0x11 放在低地址中,即 0x0010 中, 0x22 放在高地址中,即 0x0011 中。
小端模式,剛好相反。我們常用的 X86 結(jié)構(gòu)是小端模式,而 KEIL C51 則為大端模式。很多的ARM,DSP都為小端模式。有些ARM處理器還可以由硬件來選擇是大端模式還是小端模式。
3.解釋圖片中的問題
int a=20;
int b=-10;
//20以十六進(jìn)制顯示:00 00 00 14
//-10以十六進(jìn)制顯示:ff ff ff f6

可見在VS的內(nèi)存存儲(chǔ)方式為小端字節(jié)序存儲(chǔ)

4.面見筆試題
百度2015年系統(tǒng)工程師筆試題:
請(qǐng)簡(jiǎn)述大端字節(jié)序和小端字節(jié)序的概念,設(shè)計(jì)一個(gè)小程序來判斷當(dāng)前機(jī)器的字節(jié)序。
//功能:設(shè)計(jì)一個(gè)小程序來判斷當(dāng)前機(jī)器的字節(jié)序。
//思路:判斷大小端存儲(chǔ),假如數(shù)據(jù)int a=20,在內(nèi)存中十六進(jìn)制表示是00 00 00 16,
//設(shè)計(jì)程序判斷第一個(gè)字節(jié)是00還是16,若是00表示是大端,反之為小端
//要點(diǎn):根據(jù)不同類型指針實(shí)現(xiàn)對(duì)數(shù)據(jù)內(nèi)存的訪問多大的空間
int main()
{
    int a = 20;
    int result = *((char*)&a);
    //char*指針表示對(duì)內(nèi)存訪問一個(gè)字節(jié)的空間
    //解引用為對(duì)應(yīng)一個(gè)字節(jié)的值
    if (result)
    {
        printf("機(jī)器是小端存儲(chǔ)");
    }
    else
    {
        printf("機(jī)器是大端存儲(chǔ)");
    }
    return 0;
}
//函數(shù)實(shí)現(xiàn):
int check()
{
    int a = 20;
    return (*(char*)&a);
}
int main()
{
    int result =check();
    //char*指針表示對(duì)內(nèi)存訪問一個(gè)字節(jié)的空間
    //解引用為對(duì)應(yīng)一個(gè)字節(jié)的值
    if (result)
    {
        printf("機(jī)器是小端存儲(chǔ)");
    }
    else
    {
        printf("機(jī)器是大端存儲(chǔ)");
    }
    return 0;
}

2.4🎓練習(xí)題🎓 1.第一題+解析😶
//輸出什么?
#includeint main()
{
? ? char a= -1;
? ? signed char b=-1;
? ? unsigned char c=-1;
? ? printf("a=%d,b=%d,c=%d",a,b,c);
? ? return 0;
}
//char取值范圍是:0~255
//char a在內(nèi)存中的二進(jìn)制為:(負(fù)數(shù))
//原碼:1000 0000 0000 0000 0000 0000 0000 0001
//反碼:1111 1111 1111 1111 1111 1111 1111 1110
//補(bǔ)碼:1111 1111 1111 1111 1111 1111 1111 1111
//由于是char類型占一個(gè)字節(jié),需要整型提升:取后八位
//1111 1111,整型提升原則:前面與補(bǔ)符號(hào)位相同的
//1111 1111 1111 1111 1111 1111 1111 1111為整型提升后的補(bǔ)碼
//打印格式為%d有符號(hào)整型數(shù)據(jù):
//原碼:補(bǔ)碼取反(符號(hào)位不變)+1
//1000 0000 0000 0000 0000 0000 0000 0001:-1
//signed char b=-1和char a=-1結(jié)果是一樣的--->-1

unsigned char c=-1;
//參考上面可知且unsigned表示不區(qū)分符號(hào)位,統(tǒng)一按數(shù)值位看,全為正數(shù)
//原碼:1000 0000 0000 0000 0000 0000 0000 0001
//反碼:1111 1111 1111 1111 1111 1111 1111 1110
//補(bǔ)碼:1111 1111 1111 1111 1111 1111 1111 1111
//由于是char類型占一個(gè)字節(jié),需要整型提升:取后八位
//1111 1111,整型提升原則:由于是無符號(hào),不區(qū)分負(fù)數(shù),所以前面補(bǔ)0
//0000 0000 0000 0000 0000 0000 1111 1111:2^8-1=255

最終結(jié)果:a=-1,b=-1,c=255

🌞補(bǔ)充一張“輪回轉(zhuǎn)生”🌞

正確理解char的取值范圍

2.第二題+解析😶
2.
#includeint main()
{
? ? char a = -128;
? ? printf("%u\n",a);
? ? return 0;
}
char a=-128;//a是負(fù)數(shù)
//a的原碼:1000 0000 0000 0000 0000 0000 1000 0000
//a的反碼:1111 1111 1111 1111 1111 1111 0111 1111
//a的補(bǔ)碼:1111 1111 1111 1111 1111 1111 1000 0000
//由于是char類型占一個(gè)字節(jié),需要整型提升:取后八位
//1000 0000,整型提升原則:補(bǔ)符號(hào)位1
//1111 1111 1111 1111 1111 1111 1000 0000為整型提升后的結(jié)果
//打印格式為:無符號(hào)整型,最前面的符號(hào)位看作數(shù)據(jù)位
//1111 1111 1111 1111 1111 1111 1000 0000=4294967168

最終結(jié)果:4294967168

3.第三題+解析😶
3.
#includeint main()
{
? ? char a = 128;
? ? printf("%u\n",a);
? ? return 0;
}
//a是正數(shù),原碼反碼補(bǔ)碼相同
//a的原碼:0000 0000 0000 0000 0000 0000 1000 0000
//a的補(bǔ)碼:0000 0000 0000 0000 0000 0000 1000 0000
//由于是char類型占一個(gè)字節(jié),需要整型提升:取后八位
//1000 0000,整型提升原則:補(bǔ)符號(hào)位1
//1111 1111 1111 1111 1111 1111  1000 0000為整型提升后的補(bǔ)碼
//打印格式為:無符號(hào)整型,最前面的符號(hào)位看作數(shù)據(jù)位
//1111 1111 1111 1111 1111 1111  1000 0000=4,294,967,168
4.第四題+解析😶
int main()
{
    int i = -20;
    unsigned int j = 10;
    printf("%d\n", i + j);
    //按照補(bǔ)碼的形式進(jìn)行運(yùn)算,最后格式化成為有符號(hào)整數(shù)
    return 0;
}
//i為負(fù)數(shù):符號(hào)位為1
//原碼:1000 0000 0000 0000 0000 0000 0001 0100
//反碼:1111 1111 1111 1111 1111 1111 1110 1011
//補(bǔ)碼:1111 1111 1111 1111 1111 1111 1110 1100
//j為無符號(hào)整數(shù)
//原碼=補(bǔ)碼:0000 0000 0000 0000 0000 0000 0000 1010
//i+j
//1111 1111 1111 1111 1111 1111 1110 1100
//0000 0000 0000 0000 0000 0000 0000 1010
//補(bǔ)碼結(jié)果:1111 1111 1111 1111 1111 1111 1111 0110
//原碼:補(bǔ)碼按位取反+1
//1000 0000 0000 0000 0000 0000 0000 1010=-10

計(jì)算結(jié)果為:-10

5.第五題+解析😶
 ? unsigned int i;
? ? for(i = 9; i >= 0; i--)
? ? {
? ? printf("%u\n",i);
? ? }
由于int i是無符號(hào)整型,所以取值不可能小于(<)0.
所以程序中的i>=0判斷條件,不論i--恒成立,輸出結(jié)果會(huì)發(fā)生死循環(huán)
6.第六題+解析😶
int main()
{
? ? char a[1000];//字符型數(shù)組
? ? int i;
? ? for(i=0; i<1000; i++)
? ? {
? ? ? ? a[i] = -1-i;//分別對(duì)數(shù)組的每一個(gè)元素賦值
? ? ? ? //-1 -2 ...-128 127 126 ...0 1...
? ? }
? ? printf("%d",strlen(a));
? ? //strlen讀取字符串長(zhǎng)度,直到\0才停止,\0的ASCII值為0.也就是說strlen統(tǒng)計(jì)的是0之前有多少個(gè)元素
? ? //從-1到-128到0一共有255個(gè)元素
? ? return 0;
}
因?yàn)閏har的取值范圍在-128~127之間,對(duì)數(shù)組賦值到char數(shù)組中不可能超出這個(gè)范圍
所以計(jì)算結(jié)果為:255
7.第七題+解析😶
unsigned char i = 0;
int main()
{
? ? for(i = 0;i<=255;i++)
? ? {
? ? ? ? printf("hello world\n");
? ? }
? ? return 0;
}
同理,i<=255判斷條件不論i++恒為真,程序會(huì)不斷打印陷入死循環(huán)

注意:特別關(guān)注題目中以及編程過程中遇到unsigned,可能會(huì)發(fā)生bug👾


3.🌜浮點(diǎn)型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)🌛

常見的浮點(diǎn)數(shù)有哪些呢?

比如:
3.1415926
1E10:E+數(shù)字表示10的數(shù)字次方
浮點(diǎn)數(shù)家族:float double等等
浮點(diǎn)數(shù)的范圍:需要在float.h中查看
--->使用evenrything 這個(gè)軟件搜索limits.h和float.h可以查看在C語言中double和float的取值范圍。
3.1拋磚引玉💡

我們先看下面這個(gè)例子

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;
}

接下來解釋一下輸出的結(jié)果:

int n = 9;
//n的值為整型
float *pFloat = (float *)&n;
//取n的地址強(qiáng)制類型轉(zhuǎn)換為浮點(diǎn)型指針類型,將取到的地址放到變量pFloat中,變量pFloat的類型是浮點(diǎn)型指針
printf("n的值為:%d\n",n);
//此時(shí)以整型打印整型n的值:結(jié)果為9
printf("*pFloat的值為:%f\n",*pFloat);
//對(duì)pFloat浮點(diǎn)型指針進(jìn)行解引用操作,以浮點(diǎn)型打印整型n的結(jié)果:為0.0000000
*pFloat = 9.0;
//間接修改n的值為9.0浮點(diǎn)型
printf("num的值為:%d\n",n);
//以整型打印浮點(diǎn)數(shù)n的值:9.0000000
 printf("*pFloat的值為:%f\n",*pFloat);
//對(duì)pFloat浮點(diǎn)型指針進(jìn)行解引用操作,以浮點(diǎn)型打印整型n的結(jié)果:為9.000000

也就是說:整型數(shù)據(jù)用整型輸出,用浮點(diǎn)型輸出結(jié)果會(huì)發(fā)生變化,說明在內(nèi)存中浮點(diǎn)型數(shù)據(jù)和整形數(shù)據(jù)的存儲(chǔ)方式不同。接下來詳細(xì)介紹:

3.2浮點(diǎn)數(shù)的存儲(chǔ)規(guī)則
根據(jù)國(guó)際標(biāo)準(zhǔn)IEEE(電氣和電子工程協(xié)會(huì)) 754,任意一個(gè)二進(jìn)制浮點(diǎn)數(shù)V可以表示成下面的形式:
1. (-1)^S * M * 2^E
2. (-1)^s表示符號(hào)位,當(dāng)s=0,V為正數(shù);當(dāng)s=1,V為負(fù)數(shù)。
3. M表示有效數(shù)字,大于等于1,小于2。
4. 2^E表示指數(shù)位。
//舉例說明
float num=5.0
//在內(nèi)存中十進(jìn)制轉(zhuǎn)換為二進(jìn)制存儲(chǔ)的方式可以寫成:
101.0
//又可以表示成:
1.010*2^2
//對(duì)應(yīng):(-1)^S * M * 2^E,可以表示為:
(-1)^0*1.010*2^2
//計(jì)算得出:
S=0;M=1.010;E=2
IEEE 754規(guī)定:
對(duì)于32位的浮點(diǎn)數(shù),最高的1位是符號(hào)位s,接著的8位是指數(shù)E,剩下的23位為有效數(shù)字M。

在32位機(jī)器下,內(nèi)存中的存儲(chǔ)格式

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

在64位機(jī)器下,內(nèi)存中的存儲(chǔ)格式

對(duì)于指數(shù)M的特別規(guī)定:

IEEE 754規(guī)定,在計(jì)算機(jī)內(nèi)部保存M時(shí),默認(rèn)這個(gè)數(shù)的第一位總是1,因此可以被舍去,只保存后面的
xxxxxx部分。比如保存1.01的時(shí)
候,只保存01,等到讀取的時(shí)候,再把第一位的1加上去。這樣做的目的,是節(jié)省1位有效數(shù)字。以32位
浮點(diǎn)數(shù)為例,留給M只有23位,
將第一位的1舍去以后,等于可以保存24位有效數(shù)字。
//也就是說,上面的舉例中:這樣做可以提高保存在內(nèi)存中的數(shù)據(jù)的精度
M=0.010

對(duì)于指數(shù)E的特別規(guī)定:

首先,E為一個(gè)無符號(hào)整數(shù)(unsigned int)
這意味著,如果E為8位,它的取值范圍為0~255;如果E為11位,它的取值范圍為0~2047。但是,我們
知道,科學(xué)計(jì)數(shù)法中的E是可以出
現(xiàn)負(fù)數(shù)的,所以IEEE 754規(guī)定,存入內(nèi)存時(shí)E的真實(shí)值必須再加上一個(gè)中間數(shù),對(duì)于8位的E,這個(gè)中間數(shù)
是127;對(duì)于11位的E,這個(gè)中間
數(shù)是1023。比如,2^10的E是10,所以保存成32位浮點(diǎn)數(shù)時(shí),必須保存成10+127=137,即
10001001。
指數(shù)E從內(nèi)存中取出還可以再分成三種情況:
E不全為0或不全為1
這時(shí),浮點(diǎn)數(shù)就采用下面的規(guī)則表示,即指數(shù)E的計(jì)算值減去127(或1023),得到真實(shí)值,再將
有效數(shù)字M前加上第一位的1。(因?yàn)橹癕存儲(chǔ)的是0.xxxxx,需要再把1補(bǔ)回來)
比如:
0.5(1/2)的二進(jìn)制形式為0.1,由于規(guī)定正數(shù)部分必須為1,即將小數(shù)點(diǎn)右移1位,則為
1.0*2^(-1),其階碼為-1+127=126,表示為
01111110,而尾數(shù)1.0去掉整數(shù)部分為0,補(bǔ)齊0到23位00000000000000000000000,則其二進(jìn)
制表示形式為:
0 01111110 00000000000000000000000
E全為0
這時(shí),浮點(diǎn)數(shù)的指數(shù)E等于1-127(或者1-1023)即為真實(shí)值(指數(shù)級(jí)為負(fù)已經(jīng)相當(dāng)小了)
有效數(shù)字M不再加上第一位的1,而是還原為0.xxxxxx的小數(shù)。這樣做是為了表示±0,以及接近于
0的很小的數(shù)字。
E全為1
如果有效數(shù)字M全為0,表示±無窮大(正負(fù)取決于符號(hào)位s);
3.3解釋拋磚引玉的結(jié)果
//在32位平臺(tái)下
int main()
{
    int n = 9;
? ? //n為正數(shù),原碼反碼補(bǔ)碼相同:0000 0000 0000 0000 0000 0000 0000 1001
    float *pFloat = (float *)&n;
    printf("n的值為:%d\n",n);
    printf("*pFloat的值為:%f\n",*pFloat);
? ? //將整數(shù)9按照浮點(diǎn)數(shù)存儲(chǔ)規(guī)則進(jìn)行會(huì)出現(xiàn)如下結(jié)果:
? ? 0 00000000 00000000000000000001001
? ? S=0;E=00000000;M=00000000000000000001001//符合E全為0的情況
? ? //也就是:(-1)^0*0*2^(-118)
? ? 打印結(jié)果為:0.000000
    *pFloat = 9.0;
? ? //此時(shí)n看作是浮點(diǎn)數(shù)
    printf("num的值為:%d\n",n);
? ? //以整型的方式打印浮點(diǎn)數(shù):需要先將浮點(diǎn)數(shù)在內(nèi)存中取出.我們先看9.0存入內(nèi)存的方式
? ? //9.0用二進(jìn)制表示為:
? ? 1001.0
? ? //進(jìn)一步用浮點(diǎn)數(shù)表示為:
? ? (-1)*0*1.001*2^3
? ? //此時(shí)S=0,M=1.001,E=3
? ? //存儲(chǔ)在內(nèi)存時(shí):S=0,M=0.001,E=3+127=130
? ? 用二進(jìn)制表示為:0 10000010 00100000000000000000000
? ? //以整型方式顯示:01000001000100000000000000000000
? ? //通過二進(jìn)制轉(zhuǎn)十進(jìn)制的方式得出:
? ? 1,091,567,616
    printf("*pFloat的值為:%f\n",*pFloat);
? ? //以浮點(diǎn)數(shù)形式打印浮點(diǎn)數(shù)9.0,結(jié)果為:
? ? 9.000000
    return 0;
}

注意:

  1. 浮點(diǎn)數(shù)舉例避免舉小數(shù)點(diǎn)太復(fù)雜的例子,因?yàn)榈贸鲋笖?shù)E+127很難用二進(jìn)制表示,理解即可👌

2.解釋了為什么我們?cè)诰幊虝r(shí)有些數(shù)據(jù)用float和double 時(shí)輸入數(shù)據(jù)相同,輸出數(shù)據(jù)有稍微差異,因?yàn)樵趦?nèi)存中存儲(chǔ)時(shí)M占的位數(shù)有所不同,也就是說:浮點(diǎn)型數(shù)據(jù)存入內(nèi)存和取出內(nèi)存會(huì)有精度缺失的現(xiàn)象。

3.4浮點(diǎn)數(shù)的相關(guān)術(shù)語字典
  1. 定點(diǎn)數(shù):指的是小數(shù)點(diǎn)位置是固定的,小數(shù)點(diǎn)位于符號(hào)位和第一個(gè)數(shù)值位之間,它表示的是純小數(shù)。

  1. 浮點(diǎn)數(shù):實(shí)數(shù)N可統(tǒng)一表示為:N=S*r^j,其中:S為尾數(shù),規(guī)定用純小數(shù)表示;j為階碼(正負(fù)均可,但必須為整數(shù));r是基數(shù),對(duì)二進(jìn)制而言,r=2。例如:10.0111=10100111*2^10

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧


當(dāng)前題目:”神仙修煉“之C的數(shù)據(jù)存儲(chǔ)-創(chuàng)新互聯(lián)
轉(zhuǎn)載來源:http://weahome.cn/article/dhpooe.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部