编程中小数为什么 称为浮点数?

假如我们的浮点数:

float a=1.0;

在c++中,假设a占用四个字节,则该数可以由32位的0和1表示。具体表示如下:

00111111100000000000000000000000
符号位 阶位     尾数

翻译一下:

符号位: 代表着该数值的正负

阶位: 阶位大小减去127后的值代表着小数点移动的位数

尾数:代表以1开头小数点后面的数字:1.00000000000......(23位)(这里注意以下,理论只有23位,但是协议要求在23位之前要放一个1,所以也可以理解有24位尾数,其中的第一位1是一个隐式位)

回到上面的例子:

0——正: 符号位为+

01111111——127:阶位为127

0000000....——1.000000....:1.000小数点后23个0

则移动的位数:127-127=0,故1.0000000...中的小数点不移动(浮动),然后将其转为10进制位+1.0;

再举个例子:0 10000101 11110110000000000000000

以上是个浮点数在内存中的表示:

第一步看符号位0,所以为正;

第二步看阶位10000101=133,所以浮动的位数位133-127=6;

第三步看尾数1.11110110000000000000000;

将其小数点浮动(移动6位)得到:1111101.10000000000000000,将其转为十进制:+125.5

综上:浮点数的浮点二字不是空穴来风,而且可以看出4字节的浮点数小数位最多有23位,转为十进制最多为7位,这也是为什么float数的精度只有7位的原因。32位浮点数表示范围介于-1.18X10+38和3.40X10+38之间,虽然浮点数表示的范围很广,但存储的尾数只有23位,因此它并不能精确表示其范围内的所有数字。

特殊bit:

浮点数转二进制

经典问题是0.1+0.2=?

首先先看0.1如何存储:

1. 0.1转为2进制

0.0001100… (重复1100)

2. 根据IEEE754可以得到下面的布局

所以可以看到其实0.1的实际浮点数是:0.100000001490116119384765625

注意

上面一开始说精度只有7位有效数字,结果0.1却可以表示出那么多,为啥? 与整数不同,因为浮点数在计算机中的存储方式(IEEE754),浮点数无法精确表示有效范围内的所有数值。有效范围内的数值是否可以被精确表示取决于有效数字M是否可以被小数域frac完全存储。例如3.5可以被精确存储,3.6无法被精确存储。

通常认为单精度浮点数的有效数字时6~7位,绝对可以保证的是6位。

说明:因为单精度浮点数使用23bit表示小数域,2的23次方是8,388,608。23位可以存储所有6位或更低的数字,以及大多数7位数字。

但是仅按6~7位有效数字使用浮点数,更保守的只使用6位的话,如果小数点后保留两位有效数字,那么整数位只能有4位有效数字,这其实是大打折扣的!

扩展

上面我们看了0.1本来翻译成十进制为1100重复,可是在最后一位bit却是1,如何按照截断的话,理论应该是0的,为什么是0呢?首先看看假如是0的话结果是多少:

0.0999999940395355224609

对比当最后一个bit是1的时候:

0.100000001490116119385

可以明显看到bit为1时,数字离0.1更近,那么有人会问,假如是0.10和0.11离0.1一样近的话如何取舍呢?结果是选择0.10,原因是选择最低有效数字为偶数,这是一种规则叫做:Round-to-Nearest-Even, 有时候也叫round-to-even.

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值