c语言单精度浮点数规格化,对浮点数的一些理解

本文详细探讨了浮点数的数值范围计算、有效位数(精度)及其内存表示,包括单精度和双精度浮点数的比较,以及为何它们不能精确表示所有实数。通过实例展示了内存中float和double的存储结构,并揭示了浮点数舍入规则。
摘要由CSDN通过智能技术生成

浮点数的范围和有效位

对于浮点数,其能表示的数值范围和其有效位如下

类型

比特位

数值范围

有效位

float

32

-3.410^38~+3.410^38

6~7位

double

64

-1.710^-308~1.710^308

15~16位

long double

128

-1.210^-4932~1.210^4932

18~19位

可见同比特位数的整型(例如int)要比浮点数(例如float)能表示的数值范围要小很多,但是需要注意的,虽然浮点数能表示的范围大,但是 它却不能精确表示在其范围内的所有实数,也就是说,它只能保证有效位的值是精确的,当表示的数值(小数部分)超过有效位时,所表示的数是无法保证精确的,甚至可以说是错误的。

那么浮点数的数值范围和有效位是如何得到的呢?

浮点数的数值范围计算

有了前面了基础,我们就可以来计算浮点数的数值范围了。以单精度(float)为例,我们知道它的指数范围(即E)为-126~+127,而M的范围为1≤M<2,实际上,对于单精度,1≤M≤2-2^(-23)(注:23为frac字段所占的比特位)。那么我们就可以得到单精度的最大值为:

同理,我们可以得到单精度的最小值为:

我们仅仅以单精度为例,用同样的方法可以计算其他精度的浮点数取值范围,在此不再赘述。

浮点数的有效位

有效位也可以理解为我们常说的精度。浮点数的精度是由尾数的位数来决定的。

对于单精度(float),它的尾数为23位,而2^23=8388608,共7位,也就是说最多能有7位有效数字,但至少能保证6位,因此其有效位为6~7位。当然我们可以通过下面的内容进一步理解。以下计算结果保留10位小数。

观察a和b的结果可以发现,0.0000001和0.0000002之间的其他数是没有办法通过单精度浮点数来精确表示的,也就是说,只有到小数点后面7位的值才是精确的,同理,观察b和c的结果,0.0000002到0.0000004之间的其他数也是不能通过单精度浮点数精确表示的,更不幸地是,这之间的数,甚至只能精确到第6位。

这也就有了单精度浮点数的有效位为6~7位的结论。根据相似的方法,我们同样可以得到双精度浮点数的有效位为15~16位的结论,这里不再赘述。

浮点数在内存中的存储

了解了这么多,我们来看一下一个小数究竟是如何在内存中存储的。以float f = 8.25f为例。其二进制表示为,可见指数实际值为3,则根据E=exp-Bias,可知exp=E+Bias=3+127=130,根据M=1+frac,可知,frac=M-1=0.0001(二进制)而

因此不难得到,8.25的在内存中的存储情况为:

s

exp

frac

0

1000 0010

0001 0000 0000 0000 0000 000

如果这个时候把这个值作为整型使用,是多少呢?没错,是1090781184

#include

intmain(intargc,char*argv[])

{

floatf= 8.25f;

int*i = ( int*)&f;

printf( "%dn",*i);

return0;

}

再说几句

关于浮点数,需要再说几句:

在二进制,第一个有效数字必定是“1”,因此这个“1”并不会存储。

浮点数不能精确表示其范围内的所有数。

可精确表示的数不是均匀分布的,越靠近0越稠密。

默认舍入方式为向偶舍入,也被称为最接近的值舍入。

不遵守普遍的算数属性,比如结合律。

【关于作者】

huyanbing:一个好文学,好技术的开发者。

【关于投稿】

如果大家有原创好文投稿,请直接给公号发送留言。返回搜狐,查看更多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值