浮点数在内存是如何存储的

IEEE二进制浮点数算术标准IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number)),一些特殊数值(无穷(Inf)与非数值(NaN)),以及这些数值的“浮点数运算符”;它也指明了四种数值舍入规则和五种例外状况(包括例外发生的时机与处理方式)。

IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。只有32位模式有强制要求,其他都是选择性的。大部分编程语言都有提供IEEE浮点数格式与算术,但有些将其列为非必需的。例如,IEEE 754问世之前就有的C语言,有包括IEEE算术,但不算作强制要求(C语言的float通常是指IEEE单精确度,而double是指双精确度)。

该标准的全称为IEEE二进制浮点数算术标准(ANSI/IEEE Std 754-1985),又称IEC 60559:1989,微处理器系统的二进制浮点数算术(本来的编号是IEC 559:1989)。后来还有“与基数无关的浮点数”的“IEEE 854-1987标准”,有规定基数为2跟10的状况。最新标准是“ISO/IEC/IEEE FDIS 60559:2010”。

这里我们用32位机器来讲述

总体来说,浮点数我们可以用(-1)* S * M * 2 ^ E 来表示。

其中S表示符号位,当S为0,即正数,S为1即负数,要注意的是S只有一个比特位的大小。

M表示有效数字,他是一个大于1小于二的数,M的大小就是23个比特位。

2 ^ E表示指数位。E是一个无符号的整型,大小为8个比特位。

可以用一个图来表示

 

因为E是一个8bit位的无符号整数,他的取值范围就是0-255.但是科学计数法中E可以为负数的,

所以在将E存入内存时要加上一个中间值,8位的中间值是127,所以当E存入内存前都要加127。

M存入内存的有23个bit位,因为他的大小是大于1小于2的,所以我们存进去的值是小数点后的数,

不存1,这样我们存的位相当于24位,利用的空间更大,当取出来时再加上1即可。

下面我们用5.5为例,解释一下:

5.5在用二进制表示为101.1(其中101表示5,.1表示2的-1次方,也就是二分之一\0.5

(-1) * 0 * 1.011 * 2 ^ 2  (0表示S,1.011表示M,E表示2)

那么我们将他存入内存是怎么样的呢?

 

可以看到,5.5是正数,符号位是0,101.1要变成大于1小于2的数字,就要向前移动两位,E就是2

再加上127就是129,129的二进制就是上图所示,101.1向前移动两位就是1.011,将小数点后的数

存入M,不足23位补0,所以M也就如上图所示。

再用一个题来加深印象。

 

int main()
{
	int a = 9;
	float* pa = &a;
	printf("%d\n", a);
	printf("%f\n", *pa);
	*pa = 9.0f;
	printf("%d\n", a);
	printf("%f\n", *pa);
	return 0;
}

这里可以看到打印的值不一样,分析一下。

①:a为整型,用%d打印,输出结果是9,这个没问题。

②:把a的地址取出放入float指针变量pa里,为什么打印出来的是0呢?

9的二进制表示就是    00000000000000000000000000001001

 我们用浮点数来取出这个内存,会认为第一位是符号位,为0,第二到第九位是指数位,也是0

(有个知识点:当E的值位全0时,表示这个数是1.XXXX 乘上2的-128次方,此时这个数是有个无限接近与0的数,于是标准规定,M取出时不再加1,因为他已经无限接近0了,加不加已经没意义了。当E的值为全1时,这个数是个正负无穷大的数,正号负号由符号位来决定,因为1.XXXX乘上2的127次方是一个很大的数。)

所以打印出来的结果就是0.000000;

③:已经通过pa解引用将a的值改为9.0,那么再解引用得到9.00000也可以理解。

④:再通过整型来输出,那么此时内存里的a的二进制是0 10000010 00100000000000000000000

我们用整型来输出,会认为这个是一个正数,正数的原反补码一样,就会将这个数直接输出。

下面我们再通过内存来观察一下。

 

 

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值