【数据结构】定点数、浮点数是如何使用二进制实现的

Fist:why?

有时候只知道什么还不够,我们还需要为什么,所以我在整个数据结构系列中都要追寻这个答案。
Q1:为什么需要浮点型数据。
与整型数据一样,小数应用也是十分广泛,尤其是在高等数学方面。
由于计算机最初设计来就是为了进行数学计算的,所以小数出现是理所当然的。

至于在计算机中为什么小数会分成两类,等你看完这篇文章就明白了。

小数是如何使用二进制实现的

上一篇我们介绍了有符号无符号数在计算机低层如何表达。
1.整数类型之有符号、无符号数(原码、反码、补码)详解。
今天就讲一下小数在计算机低层如何实现的。

1. 定点数

定点数是很早很早就出现的数据类型,几乎在计算机出现没多久就出现了。
其实这也是很符合历史发展规律的,当人们找到合适的表达有符号数之后,
用定点数表达小数也是很理所应当的。

像有符号数一样我们,人为指定了一位数表达正负,定点数就是我们人为的指定,二进制数字的一部分表示小数的整数部分、一部分表示小数的小数部分,这样来表示小数。

小数点位固定在最后一位之后称为定点整数,小数点固定在最高位之后称为定点小数。

2. 浮点数

2.1科学记数法与浮点数

说到浮点数,我觉得使用科学记数法这样来理解时最好的。
科学记数法例:+1.99714×10^13
由符号位,数值和幂数表示。其中幂数表明数字值的小数点往前或往后(当幂数为正时)移动多少位。
浮点数也是这样的的,采用科学记数法,实现小数点位置的浮动,这样的大大增加了能表达的数字精确度,而且也能够,更好的计算。

根据国际标准IEEE 754/854,任意一个二进制浮点数V可以表示成下面的形式:
V = (-1)^s ×M×2^E
(1)(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
(2)M表示有效数字,大于等于1,小于2。
(3)2^E表示指数位。

单精度浮点数格式
其中s:取值为0,1。0为正;
E为有符号整数,取值为 -126~+127;
M为无符号整数,取值为0-2^22,其实际值为1.M(二进制);

也就是说单精度浮点数最大精度为:
±1.00000000000000000000001 X 2^-126
转换为十进制数字是:
(1+2^-23) X (2^-126) = 1.401298 X 10^-45
但是:别看取值能取到10的负45次方,其实单精度浮点数的精度只有7位。
单精度浮点数的实际有效精度为24位二进制,这相当于24*log102≈7.2位10进制的精度,所以平时我们说“单精度浮点数具有7位精度”

2.2浮点数的特殊数值

IEEE 标准指定了以下特殊值:±0、反向规格化的数、±∞ 和 NaN(如下表所示)。这些特殊值都是使用 emax+1 或 emin-1 的指数进行编码的。

在这里插入图片描述

NaN:当指数段 exp 全为 1 时,小数段为非零时,结果值就被称为“NaN”(Not any Number),如图 3 所示。
无穷:当指数段 exp 全为 1,小数段全为 0 时,得到的值表示无穷。当 s=0 时是 +∞,或者当 s=1 时是 -∞

2.3浮点数的舍入误差

在浮点数的舍入问题上,IEEE 浮点格式定义了 4 种不同的舍入方式,如下表所示。其中,默认的舍入方法是向偶数舍入,而其他三种可用于计算上界和下界。
在这里插入图片描述
偶数舍入:四舍六入五成双

这种约定的问题在于,人们可以很容易地想象
在这种情况下,舍入一组数据值将引入统计偏差
计算平均值。一组数字的平均值
我们用这种方法四舍五入的结果会略高于
数字本身。相反,如果我们总是把数字四舍五入到一半
从下到下,一组四舍五入数的平均值是
略低于数字本身的平均值。四舍五入
在现实生活中,偶数可以避免这种统计偏差。
它将在大约50%的时间内向上舍入,在大约50%的时间内向下舍入。

这是IEEE里对偶数舍入的解释百度翻译。
就是舍入位的奇偶性决定是否进位。
例:10.0(10), 10.0(11), 10.1(10), 11.0(01)向偶数舍入(保留小数点后一位)的结果分别为10.0, 10.1, 11.0, 11.0。
这样是为了避免统计偏差。

2.4不是总可靠的浮点数

正如我上面所讲的,单精度浮点数取值能取到10的负45次方,但是由于其数值位只有24位,所以它的精度只有七位。

而且最重要的还有一点,在十进制转换二进制计算的过程中会出现溢出的情况!
就是老师讲课都说过的float不精确。这也是在一些编程过程中容易出现的问题,包括在数据库等都会出现这个问题。
就像一个简单的0.1使用二进制表示需要
0 01111011 10011001100110011001101

s=0 e=123 尾数部分的隐含位为1 所以尾数是1.10011001100110011001101
以上二进制数据流对应的二进制数学运算表达式为:
(-1)0*2123-1271.10011001100110011001101
即2^-4 X 1.10011001100110011001101
即2^23 X 1.10011001100110011001101 X 2^-27
即110011001100110011001101
2^-27
即13421773*2^-27
=0.100000001490116119384765625
与0.1误差0.000000001490116119384765625
所以说并不精确,但是这个问题并不是不能解决的,在高级语言中都出现的特定的数据结构,来解决高精度数字,比如,java的BigDecimal,python的Decimal等等。
参考:IEEE 754浮点数标准详解

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值