C++ float的内存布局
IEEE754標(biāo)準(zhǔn)中,浮點(diǎn)數(shù)的內(nèi)存布局
以下僅以float(內(nèi)存中占據(jù)4個(gè)字節(jié),32bits)來(lái)說(shuō)明,double(8個(gè)字節(jié),64bits)同理,只是有細(xì)微的差別。
float的內(nèi)存分布
IEEE754規(guī)定,32bit的float在內(nèi)存中是這樣分布的:
| 1 | 8 | 23 |
整數(shù)、浮點(diǎn)數(shù)在內(nèi)存中都是以二進(jìn)制的形式存在的(補(bǔ)碼),而浮點(diǎn)數(shù)是二進(jìn)制下的科學(xué)計(jì)數(shù)法存儲(chǔ)在內(nèi)存中的。可以表示 為:$ s 1.m^e$
- 符號(hào)位占據(jù)一個(gè)比特,當(dāng)S = 0時(shí)表示正數(shù),當(dāng)S = 1時(shí)表示負(fù)數(shù)。
- 階碼e則是其指數(shù)再加上一個(gè)偏移量(127)后的數(shù),其總共占據(jù)了8個(gè)字節(jié),8位無(wú)符號(hào)數(shù)的范圍是0~255,考慮到已經(jīng)加了一個(gè)偏移量,則其實(shí)際可表達(dá)的范圍是-128~127(這個(gè)范圍是指二進(jìn)制計(jì)數(shù)法下的范圍)。
- 尾數(shù)m占據(jù)了23個(gè)字節(jié),由于是使用的二進(jìn)制下的科學(xué)計(jì)數(shù)法,所以任何浮點(diǎn)數(shù)(除了0)都隱含了一個(gè)1,也就是說(shuō),其尾數(shù)實(shí)際上在前面應(yīng)該再加一個(gè)1,即:1.m,這樣,浮點(diǎn)數(shù)的二進(jìn)制精度是24位,而$2^{24} = 16777216$,所以其十進(jìn)制下的精度是7位有效數(shù)字。
計(jì)算實(shí)例
1, 十進(jìn)制與二進(jìn)制的互轉(zhuǎn)
二進(jìn)制轉(zhuǎn)十進(jìn)制比較簡(jiǎn)單,就是對(duì)應(yīng)位乘以對(duì)應(yīng)的2的冪次,比如:101.1011,其轉(zhuǎn)換過(guò)程為:
$$1*2^2 + 0 * 2^1 + 1 * 2^0 + 1 * 2^{-1} + 0 * 2^{-2} + 1 * 2^{-3} + 1 * 2^{-4}$$
十進(jìn)制整數(shù)轉(zhuǎn)二進(jìn)制比較簡(jiǎn)單,一是8421來(lái)湊,一是除2倒序排,不再解釋。
十進(jìn)制小數(shù)轉(zhuǎn)二進(jìn)制,就是一直乘2,如果大于1,則置1,如果小于1,則置0,一直乘2,直到為0或達(dá)到指定位數(shù)為止。
比如0.125:
$$ 0.25 * 2 = 0.5 --- 0 \\ 0.5 * 2 = 1 --- 1$$
則其二進(jìn)制為:0.01。
再比如:0.632:
$$ 0.632 * 2 = 1.264 --- 1 \\ 0.264 * 2 = 0.528 ---0 \\ 0.528 * 2 = 1.056 ---1 \\ 0.056 * 2 = 0.112 ---0 \\ ...$$
則其二進(jìn)制為:0.1010….。
2, 計(jì)算float的內(nèi)存布局
2.1 考慮float fa = 4.25,那么:int ia = *(int*)&fa是多少呢?
我們知道,4.25 = 100.01,化成指數(shù)表示為:$1.0001*2^2$,則其符號(hào)位S = 0, 階碼e = 2 + 127 = 0x81,其尾數(shù)部分二進(jìn)制表示為:1000 1000 0000 0000 0000 0000,總共24位,將尾數(shù)的最高位的1去掉,再與階碼e,符號(hào)位S組合后:
| 0 | 1000 0001 | 000 1000 0000 0000 0000 0000 |
合起來(lái)就是:
0100 0000 1000 1000 0000 0000 0000 0000,即:ia = 0x40880000。
2.2 再考慮float fa = -0.0125,那到:c++ int ia = *(int*)&fa是多少呢?
-0.0125 = -0.00000011001100110011001100...,轉(zhuǎn)換成指數(shù)為:$-1.10011001100110011001100…*2^{-7}$,則其符號(hào)位S = 1,階碼e = -7 + 127 = 0x78,其尾數(shù)部分用二進(jìn)制表示為:1100 1100 1100 1100 1100 1101,后面的位數(shù)就被四舍五入截?cái)嗔?#xff0c;由于最后一位的后一位是1,則向前進(jìn)1,同樣保留24位,將其最高位的1去掉,再與階碼和符號(hào)位組合:
| 1 | 0111 1000 | 100 1100 1100 1100 1100 1101 |
全起來(lái)就是:
1011 1100 0100 1100 1100 1100 1100 1101,即:ia = 0xbc4ccccd。
如果將ia轉(zhuǎn)換成fa,則轉(zhuǎn)換過(guò)程相反。
來(lái)自為知筆記(Wiz)
轉(zhuǎn)載于:https://www.cnblogs.com/beichen2012/p/5756321.html
總結(jié)
以上是生活随笔為你收集整理的C++ float的内存布局的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Wpf控件ListBox使用实例2
- 下一篇: C++基础知识总结(一)