C++/C--浮点型数据的二进制表示及其内存存储形式

二进制表示

以12.123为例:

12/2 = 6---------------------0

6/2 = 3----------------------0

3/2 = 1----------------------1

1/2 = 0----------------------1

所以整数部分是1100

0.123*2 = 0.246-----------0

0.246*2 = 0.492-----------0

0.492*2 = 0.984-----------0

0.984*2 = 1.968-----------1

0.968*2 = 1.936-----------1

所以小数部分0.00011
故:12.123=1100.00011

来源于:https://wenwen.sogou.com/z/q860121447.htm

存储形式
float型实数在内存中占4个字节,即32个二进制bit,从低位到高位依次叫第0位到第31位。这32位可以分为3个部分:符号位(第31位),阶码(第30位到第23位共8位),尾数(最低23位)。

  1. 符号位
    最高位也就是第31位表示这个实数是正数还是负数,为0表示正数或0,为1表示负数.
  2. 阶码
    第30位到第23位这8个二进制位表示该实数转化为规格化的二进制实数后的指数与127(127即所谓偏移量)之和即所谓阶码.
  3. 尾数
    其他最低的23位即第22位到第0位表示该实数转化为规格化的二进制实数后小数点以后的其余各位即所谓尾数

例如,将十进制178.125表示成机器内的32个字节的二进制形式. 
第一步:将178.125表示成二进制数:(178.125)(十进制数)=(10110010.001)(二进制形式);
第二步:将二进制形式的浮点数转化为规格化的形式:(小数点向左移动7个二进制位可以得到
10110010.001=1.0110010001*2^7 因而产生了以下三项:
符号位:该数为正数,故第31位为0,占一个二进制位;
阶码:指数为7,故其阶码为127+(7)=134=10000110,占从第30到第23共8个二进制位;
尾数为小数点后的部分, 即0110010001.因为尾数共23个二进制位,在后面补13个0,即01100100010000000000000
所以,178.125在内存中的实际表示方式为:
0 10000110 01100100010000000000000

再如,将-0.15625表示成机器内的32个字节的形式.
第一步:将-0.15625表示成二进制形式: (-0.15625)(十进制数)=(-0.00101)(二进制形式);
第二步:将二进制形式的浮点数转化为规格化的形式:(小数点向右移动3个二进制位可以得到)
-0.00101=-1.01*2^(-3) 同样,产生了三项:
符号位:该数为负数,故第31位为1,占一个二进制位;
阶码:指数为-3,故其阶码为127+(-3)=124=01111100,占从第30到第23共8个二进制位;
尾数为小数点后的01,当然后面要补21个0;
所以,-0.15625在内存中的实际表示形式为:
1 01111100 01000000000000000000000

程序验证:

#include 
#include 
void printfFloatBit(float f)
{ 
	int i,j;
	unsigned int byte=0;
	char ch,*p;
	p=(char *)(&f);
	printf(" .7f: ",f);
	for(i=sizeof(float)-1;i>=0;i--)
	{
		ch=*(p+i);
		byte=ch;
		for(j=1;j <=8;j++)
			 {
				  if(byte>=128) printf("1");
				  else printf("0");
				  byte <<=1;
				  byte&=255;
			 }
	}
 printf("\n");
}

void main()
{
	float f1=178.125; 
	float f2=-0.15625;
	float f3=1.0;
	system("cls");
	printfFloatBit(f1);
	printfFloatBit(f2);
	printfFloatBit(f3);
	system("pause");
}

来源于:https://wenku.baidu.com/view/45a48d1a227916888486d784.html

你可能感兴趣的:(C/C++)