存儲方式
方式 | 位數(shù) | 標(biāo)準(zhǔn) | 模式 |
---|---|---|---|
float | 32bit | IEEE R32.24 | |
double | 64bit | R64.53 |
- 符號位(Sign):0代表正,1代表為負(fù)瘫俊;
- 指數(shù)位(Exponent):用于存儲科學(xué)計數(shù)法中的指數(shù)數(shù)據(jù),并且采用移位存儲;
- 尾數(shù)部分(Mantissa):尾數(shù)部分
R32.24和R64.53的存儲方式都是用科學(xué)計數(shù)法來存儲數(shù)據(jù)的
用二進(jìn)制的科學(xué)計數(shù)法第一位都是1穷当,可以將小數(shù)點前面的1省略,所以23bit的尾數(shù)部分淹禾,可以表示的精度卻變成了 24bit馁菜,道理就是在這里。
那24bit能精確到小數(shù)點后幾位呢铃岔,我們知道9的二進(jìn)制表示為1001汪疮,所以4bit能精確十進(jìn)制中的小數(shù)點后一位,24bit就能使float能精確到小數(shù)點后6位,而對于指數(shù)部分智嚷,因為指數(shù)可正可負(fù)躲胳,8位的指數(shù)位能表示的指數(shù)范圍就應(yīng)該為:-127-128了, 所以指數(shù)部分的存儲采用移位存儲纤勒,存儲的數(shù)據(jù)為元數(shù)據(jù)+127坯苹。
下面就看看8.25和120.5在內(nèi)存中真正的存儲方式:
8.25換算成二進(jìn)制科學(xué)計數(shù)法
8 = 1000;
0.25 = 0.01;
8.25(10) = 1000.01(2) = 1.00001*2^3
按照上面的存儲方式
符號位為 0,表示為正摇天;
指數(shù)位為 3+127=130粹湃,
尾數(shù)部分為 00001 = 00001000000000000000000 //23位
故8.25的存儲方式如下:
0--10000010--00001000000000000000000
即01000001000001000000000000000000
#同理
120.5在內(nèi)存中的存儲格式如下
0--10000101--11100010000000000000000
即01000010111100010000000000000000
那么如果給出內(nèi)存中一段數(shù)據(jù),并且告訴你是單精度存儲的話泉坐,你如何知道該數(shù)據(jù)的十進(jìn)制數(shù)值 呢为鳄?其實就是對上面的反推過程,比如給出如下內(nèi)存數(shù)據(jù):
01000001001000100000000000000000
第一步:符號位為0腕让,表示是正數(shù)孤钦;
第二步:指數(shù)位為10000010,換算成十進(jìn)制為130纯丸,所以指數(shù)為130-127=3偏形;
第三步:尾數(shù)位為01000100000000000000000,換算成十進(jìn)制為 (1+1/4+1/64);
#尾數(shù)部分都要+1
十進(jìn)制數(shù)值為:2^3*(1+1/4+1/64)=8+2+1/8=10.125
移位存儲的詳解
以32位單精度float內(nèi)存模型為例
從上圖可以看出 指數(shù)部分8位存儲空間實際上并不在意同一個字節(jié)上觉鼻,通常情況下8位存儲空間可以存儲的數(shù)值范圍為
0000000 0 ~ 1111111 1
也就是從0開始到 255結(jié)束俊扭,一共 256個數(shù)。
但是新組成的8位數(shù)是用來表示整串32位單精度浮點數(shù)的冪指數(shù)(階碼)的坠陈,而浮點數(shù)的冪指數(shù)(階碼)是有必要使用負(fù)數(shù)的萨惑。
既要表示正數(shù),又要表示負(fù)數(shù)仇矾,因此我們要拿出一位來表示正負(fù)號庸蔼,通常都是拿一個字串最左邊的那位即最高位來表示正負(fù)號的,使用傳統(tǒng)的方式贮匕,即一個字節(jié)的最高位(最左邊那位)為1時表示負(fù)數(shù)姐仅,那么我們可以得到兩個區(qū)間,這里我們?yōu)榱丝粗奖氵€是使用空格來隔開最高位的符號位和最低位的那位特殊位:
第一個區(qū)間:
0 000000 0~ 0 111111 1
即+ 0 到 127粗合,
第二個區(qū)間:
1 000000 0~ 1 111111 1
即 -0 到 - 127萍嬉,
這里出現(xiàn)了2個0,一個正+0隙疚,一個-0
使用移位存儲方式會有什么效果呢? 移位存儲要+127 , 存儲示例:
127 使用這個新生成的字節(jié)來表示壤追,則是:
0 111111 1 ,
如果我們要表示 0供屉,則有 0+127=127 即 0 111111 1
:0 000000 0 + 0 111111 1= 0 111111 1
我們要表示1行冰,則有 1+127=128 即 1 000000 0
:0 000000 1 + 0 111111 1= 1 000000 0
我們要表示 2溺蕉,則有 2+127=129 即 1 000000 1
:0 000001 0 + 0 111111 1= 1 0000001
………………………………………………………………
我們要表示 128,則有 128+127=255 即 1 111111 1
:1 000000 0+ 0 111111 1= 1 111111 1
這個128是我們能夠使用 8位二進(jìn)制移位存儲算法表示的最大的正數(shù)了悼做,再大就溢出了疯特。 同樣,我們來看看負(fù)數(shù):
我們要表示 -1時肛走,則有( -1) +127=127-1=126 即 0 111111 0
:0 111111 1 - 0 000000 1= 0 111111 1
我們要表示 -2時漓雅,則有( -2)+ 127=127-2=125 即 0 111110 1
:0 111111 1 - 0 000001 0= 0 111110 1
……………………………………………………………………………………………… 我們要表示 -127時,則有(-127)+127=127-127=0 即 0 000000 0
:0 111111 1 - 0 111111 1= 0 000000 0
這-127朽色,是我們能夠使用 8位二進(jìn)制采用移位存儲所能表示的最小的負(fù)數(shù)了邻吞,再小就溢出。
由上面的 例子葫男,我們可以得出規(guī)律抱冷,采用移位存儲技術(shù),我們可以使用 8位二進(jìn)制來表示從 -127~128 共計:
127個負(fù)數(shù)+零(0)+128個正數(shù)=256個數(shù)
看來使用移位存儲即沒有+0和-0的問題梢褐,又充分的使用這個新生成的 8位二進(jìn)制數(shù)來最大限度的表示單精度浮點數(shù)的冪指數(shù)(階碼)旺遮,是非常合理的