Open ChenPt opened 6 years ago
浮点数分为单精度和双精度。在C语言中,单精度对应的是float类型,双精度对应的是dobule类型,两者的区别就是单精度浮点数在计算机中的存储字节为4个字节也就是32位,双精度浮点数在计算机中的存储字节为8个字节,也就是64位。 根据IEEE规范,两者都是由三部分组成,且格式如下 符号位,指数位,尾数位(小数,一般讨论的精度就是指的这个) 取值范围取决为指数位,计算精度取决为小数位
对于单精度浮点数,符号位所占二进制位为1,指数为8位,尾数(小数)为23位。
对于双精度浮点数,符号位所占二进制位为1,指数为11位,尾数(小数)为52位。
对于指数位,因为需要考虑负指数和正指数,所以引入了一个偏差值,实际的指数值按要求需要加上一个偏差(Bias)值作为保存在指数域中的值。 偏差值的计算公式为 为什么是这个数呢?
首先,如果我们只有4个二进制位来存储数字,我们最多可以存储多少? 首先一个二进制位有两种取值,0或1,那么我们其实就可以存储2^4 = 16个不同的数字。 对于非负整数,其范围就是[0, 15] 对应二进制为[0000, 1111] 而如果考虑到负整数,对于十进制来说其范围可能是[-1, 14]或 [-7, 8]或[-8, 7]等等,而对于二进制,其范围还是[0000, 1111]。
[0, 15]
[0000, 1111]
[-1, 14]
[-7, 8]
[-8, 7]
对于[-7, 8],[0000, 1111],-7 这里用 0000(2)来表示,那么0011(2)表示多少呢? 因为0011实际上表示的是3, 而前面0000表示的是-7,那么我们可以推出0011其实表示的是3-7 = -4。 这里的7,就是我们所说的偏差值了。同理,对于[-8, 7],其偏差值为8。 这个范围区间怎么确定呢?其实是没有一个标准来确定的,通常是使得非负整数的个数与负整数的个数一样,也就是[-8,7]这种格式, 负整数范围为[-8, -1], 非负整数取值范围为[0, 7],两者都是8个。 而对于IEEE-754标准,它采用的是非负整数比负整数多出两个数字的区间范围分配方式,也就是[-7,8] 这种形式的。 对于非负整数和负整数个数相同的区间范围来说,计算偏差值就直接取数字个数的一半就好了,也就是 $2^(n-1)$
-7
0000(2)
0011(2)
0011
0000
3-7 = -4
[-8, -1]
[0, 7]
[-7,8]
对于单精度浮点数来说,偏差值为127,所以指数取值范围为[-127, 128]。 如果再去掉全0以及全1的情况,那么就指数范围就只剩下[-126, 127]之间。同理,双精度浮点数偏差值为1023,指数取值范围为[-1023,1024]。所以实际的指数值,为指数域中的值减去偏差值。
偏差值
IEEE标准要求小数点左侧必须为1,所以可以省略小数点前这个1,腾出一个二进制位来保存更多的尾数,所以对于单精度浮点数计算精度可以达到24个二进制位,而对于双精度浮点数计算精度可以达到53个二进制位。
JavaScrtipt的所有数字都保存为64位浮点数。
关于浮点数
浮点数分为单精度和双精度。在C语言中,单精度对应的是float类型,双精度对应的是dobule类型,两者的区别就是单精度浮点数在计算机中的存储字节为4个字节也就是32位,双精度浮点数在计算机中的存储字节为8个字节,也就是64位。 根据IEEE规范,两者都是由三部分组成,且格式如下 符号位,指数位,尾数位(小数,一般讨论的精度就是指的这个) 取值范围取决为指数位,计算精度取决为小数位
对于单精度浮点数,符号位所占二进制位为1,指数为8位,尾数(小数)为23位。
对于双精度浮点数,符号位所占二进制位为1,指数为11位,尾数(小数)为52位。
偏差值
对于指数位,因为需要考虑负指数和正指数,所以引入了一个偏差值,实际的指数值按要求需要加上一个偏差(Bias)值作为保存在指数域中的值。 偏差值的计算公式为 为什么是这个数呢?
偏差值的计算
首先,如果我们只有4个二进制位来存储数字,我们最多可以存储多少? 首先一个二进制位有两种取值,0或1,那么我们其实就可以存储2^4 = 16个不同的数字。 对于非负整数,其范围就是
[0, 15]
对应二进制为[0000, 1111]
而如果考虑到负整数,对于十进制来说其范围可能是[-1, 14]
或[-7, 8]
或[-8, 7]
等等,而对于二进制,其范围还是[0000, 1111]
。对于
[-7, 8]
,[0000, 1111]
,-7
这里用0000(2)
来表示,那么0011(2)
表示多少呢? 因为0011
实际上表示的是3, 而前面0000
表示的是-7,那么我们可以推出0011
其实表示的是3-7 = -4
。 这里的7,就是我们所说的偏差值了。同理,对于[-8, 7]
,其偏差值为8。 这个范围区间怎么确定呢?其实是没有一个标准来确定的,通常是使得非负整数的个数与负整数的个数一样,也就是[-8,7]这种格式, 负整数范围为[-8, -1]
, 非负整数取值范围为[0, 7]
,两者都是8个。 而对于IEEE-754标准,它采用的是非负整数比负整数多出两个数字的区间范围分配方式,也就是[-7,8]
这种形式的。 对于非负整数和负整数个数相同的区间范围来说,计算偏差值就直接取数字个数的一半就好了,也就是 $2^(n-1)$对于单精度浮点数来说,偏差值为127,所以指数取值范围为[-127, 128]。 如果再去掉全0以及全1的情况,那么就指数范围就只剩下[-126, 127]之间。同理,双精度浮点数偏差值为1023,指数取值范围为[-1023,1024]。所以实际的指数值,为指数域中的值减去
偏差值
。IEEE标准要求小数点左侧必须为1,所以可以省略小数点前这个1,腾出一个二进制位来保存更多的尾数,所以对于单精度浮点数计算精度可以达到24个二进制位,而对于双精度浮点数计算精度可以达到53个二进制位。
JavaScrtipt的所有数字都保存为64位浮点数。