C++ primer plus: 关于float类型只能存储6位有效数字的思考

在阅读C++ primer plus的过程中,书中提到:

 

事实上,C和C++对于有效位数的要求是,float 至少32 位,double至少48位,且不少于foat,longdouble , 至少和double 一样多。这三种类型的有效位数可以一样多。

但是,随后,其又指出:

由于cout打印6位小数,因此tub和mint都是精确的。但当程序将每个数乘以一百万后,tub在第7个3之后就与正确的值有了误差。tub 在7位有效位上还是精确的(该系统确保float至少有6位有效位,但这是最糟糕的情况)。 然而,double类型的变量显示了13个了,因此它至少有13位是精确的。由于系统确保15位有效位,这就没有什么好奇怪的了。

同样是关于有效位数的描述,为什么前后却不一样呢?

不知道是不是翻译错误,在这里两个长得一模一样的汉字却拥有不同的意思:

第一个有效数字指的是float在计算机内存中需要的内存空间大小,

第二个有效数字指的确实是数学意义上的有效数字. 

那为什么float类型在计算时的有效数字是 7位数呢?

在计算机的内存中,浮点型的存储方式如下图所示:

 

其又分为三个部分:

第一部分: 符号位

即上图中蓝色标识的部分,在内存中只占一位.类似于整形的表示方法,该位用来标识整个浮点数的正负.

第二部分:指数位 

在10进制的数中,我们一般使用科学计数法来表示较大或较小的数字,如 198000 可以表示为 1.98 * 10^5 , 又或者是表示为 1.98E5. 直观的讲,在将1.98乘上10的6次方的过程中,1.98的小数点向右移动了6位. 若10的指数为负数,同样地,小数位会向左移动. 小数点在不断的移动,这也是为什么"小数类型"会被称为浮点数的原因.

类似地,在2进制的系统中,也存在同样的科学计数法,只不过区别在于,10进制时科学计数法所使用的基底为10,而2进制中使用的基底为2.

在指数位中,存储的便是某个小数转化为科学计数法时的2的基底的指数数据. 不难发现,指数可正可负.简单的解决方案是:模仿整型,在指数位中选取一位(最高位或者最低位)来充当符号位.可惜的是,计算机科学家们并没有这么做,而是用一种更"暴力"的方式取而代之.具体的做法是:在计算机识别出指数位的数据后,将其减去127,得到的便是真正的指数数据.例如:若整数位中的数据为10000010,即为10进制的130,那么其真正的指数为130-127=3.这样一来,指数位便可以表示-127到129的所有数字了.

第三部分:尾数位

对于尾数,我的简单理解是:10进制中小数点后面的部分(当然是在该数被科学计数法表示后).例如:

8.25 的尾数部分就是0.25 , 可用二进制表示为 .01

在处理完小数部分后,再来看看整数部分.我们知道,在科学计数法的表示下, 10进制的所有数字在整数部分的大小绝不会超过10,更为确切的说,其值只能为1-9,其原因是因为在科学计数法中,10进制的数的指数部分的基底为10,这导致整数部分必须是对10取模之后的结果.同样地,在2进制中,整数部分也一定是对2取模的结果.令人惊讶的是,不像在10进制中,整数部分有9个数之多,2进制下的数字在科学计数法表示之后,整数部分只能为1.这导致了一个结果,即计算机不需要花费额外的空间来记录这个整数部分,因为它始终为1.

在解决完上面的知识后,我们终于又回到了最开始的问题,即:

为什么float类型在计算时的有效数字是 7位数?

要理解这个问题,我们只需要关于浮点数内存中的尾数位即可.已知尾数位有23位,换算成10进制后所表示的最大数为 16777215,其有8位,在化为有效数字后小数点后共有7位.可以看到,这样完美诠释了上面的问题.

我们再做一个验证,证明:double类型在计算时的有效数字是15位数.

与float类型有些许不同,double类型在存储中花费了11位来存储指数,相应的,其尾数位有64-11-1=52位.所以换算成10进制后,能表示的最大数为 9007199254740991,在化为有效数字后小数点后共有15位.验证成功.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值