小数在计算机中的储存形式

小数在计算机中的储存形式

符号位阶码尾数长度
float182332
double1115264

1)32位浮点数的换算:

float  var = 5.2f;

0.2*2 = 0.4 * 20 = 0.8 * 2 0= 1.6(0.6) * 2 1= 1.2(0.2)*2 1= 0.4 * 2 0= 0.8 * 2 0= 1.6(0.6) * 2 1= 1.2 1… … -->00110011…
因此,这里把0.2的二进制就计算出来了,结果就为:0.00110011… 这里的省略号是你没有办法计算完。二进制序列无限循环,没有到达结果为0的那一天。那么此时我们该怎么办?这里就得取到一定的二进制位数后停止计算,然后舍入。我们知道,float是32位,后面尾数的长度只能最大23位。因此,计算结束的时候,整数部分加上小数部分的二进制一共23位二进制。因此5.2的二进制就表示为:101.00110011001100110011一共23位。
此时,使用科学计数法表示,结果为:
1.0100110011001100110011 ∗ 2 2 1.0100110011001100110011*2^2 1.010011001100110011001122

由于我们规定,使用二进制科学计数法后,小数点左边必须为1(肯定为1嘛,为0的话那不就是0.xxxx*xxxx 了,这样没有什么意义),这里不能为0是有一个很大的好处的,为什么?因为规定为1,这样这个1就不用存储了,我们在从16进制数换算到浮点数的时候加上这个1就是了,因为我们知道这里应该有个1,省略到这个1的目的是为了后面的小数部分能够多表示一位,精度就更高一些了哟。那么省略到小数点前面的1后的结果为:
. 01001100110011001100110 ∗ 2 2 .01001100110011001100110*2^2 .0100110011001100110011022

这里后面蓝色的0就是补上的,这里不是随便补的一个0,而是0.2的二进制在这一位上本来就应该为0,如果该为1,我们就得补上一个1.是不是这样多了一位后,实际上我们用23位表示了24位的数据量。有一个位是隐藏了,固定为1的。我们不必记录它。
但是,在对阶或向右规格化时,尾数要向右移位,这样被右移的尾数的低位部分会被丢掉,从而造成一定的误差,因此要进行舍入处理。 常用的舍入方法有两种:一种是“0舍1入”法,即如果右移时被丢掉数位的最高位为0则舍去,为1则将尾数的末位加“1”,另一种是“恒置1”,即只要数位被移掉,就在尾数的末位恒置“1”。

举个例子:
123.456的二进制到23位时:111 1011.0111 0100 1011 1100 01…
后面还有依次为01…等低位,由于最高位的1会被隐藏,向后扩展一位如果不做舍入操作则结果为:
1.11101101110100101111000 ∗ 2 6 1.11 1011 0111 0100 1011 1100 0 *2^6 1.1110110111010010111100026

但是经过舍入操作后,由于被舍掉的位的最高位是1,或者“恒置1”法,最后面的0都应该是1。因此最终就应该是:
1.11101101110100101111001 ∗ 2 6 1.11 1011 0111 0100 1011 1100 1 *2^6 1.1110110111010010111100126

在这里需要说明,不管是恒置1,还是0舍1入法,其根本都是为了减小误差。举例到此结束。

那么,5.2的尾数在这里就计算好了就是 01001100110011001100110 。再来看阶数,这里我们知道是2^2次方,那么指数就是2。同样IEEE标准又规定了,因为中间的阶码在float中是占8位,而这个阶码又是有符号的(意思就是说,可以有2的(-2)次方的形式)。
float 类型的偏置量
B i a s = 2 k − 1 − 1 = 2 8 − 1 − 1 = 127 Bias = 2^{k-1}-1 = 2^{8-1}-1= 127 Bias=2k11=2811=127

但还要补上刚才因为左移作为小数部分的 2 位(也就是科学技术法的指数),因此偏置量为 127 + 2=129 ,就是 IEEE 浮点数表示标准:

V = (-1)s × M × 2E
E = e - Bias

中的 e ,此前计算 Bias=127 ,刚好验证了 E = 129-127 = 2。这里的阶码就是12910 ,二进制就是:1000 00012 。因此,拼接起来后为

1000 0001   01001100110011001100110  
|8位 →|   |--------23--------|

一共就是31位了,这里还差一位,那就是符号位,我们定义的是5.2,正数。因此这里最高位是0,1表示负数。而后结果就是:

0    1000 0001    01001100110011001100110  
1|-8-|    |--------23--------|

到这里,我们内存里面的十六进制数产生了,分开来看:

0 100  0000   1 010   0110   0110   0110   0110   0110
--4--  --0-   --A--   --6-   --6-   --6-   --6-   --6-

因此,我们看到的就是0x40A66666, 此就是5.2最终的存储形式。


2)64位浮点数的换算:

  • 中间的阶码在double中占有11位,因此就不是+127了,而是加上1023,因为11位能表示的最大无符号数是2047,因此有符号范围[-1024, 1023]。
  • 尾数是52位,因此精度更高,能表示的数也就越大。我们在换算5.2的时候,后面的小数二进制+前面的5的二进制再省略一位后的总位数要填满52位。

学习于https://blog.csdn.net/jjj19891128/article/details/22945441

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值