第二章 信息的表示和处理 第四节 浮点数

1、二进制小数

类比十进制小数,我们很容易理解二进制小数。
一般的十进制小数可以表示如下
在这里插入图片描述
其含义为
在这里插入图片描述
小数点向左移动一位,值变为十分之一。在小数点左边的数字权值是10的正幂,右边的是10的负幂。
同理我们可以得到一个二进制小数可以表示如下
在这里插入图片描述
其含义为
在这里插入图片描述
例如101.11 表示的数字为
1 ∗ 2 2 + 0 ∗ 2 1 + 1 ∗ 2 0 + 1 ∗ 2 − 1 + 1 ∗ 2 − 2 = 4 + 0 + 1 + 1 2 + 1 4 = 5 3 4 1*2^2 + 0 * 2^1 + 1 * 2^0 + 1*2{-1}+1*2^{-2} = 4 + 0 + 1+ \frac{1}{2} + \frac{1}{4}= 5\frac{3}{4} 122+021+120+121+122=4+0+1+21+41=543

在有限长度的编码范围内,有些数我们无法准确表示。例如十进制中的 1 3 \frac{1}{3} 31,二进制中的0.20

2、IEEE浮点表示

2.1 表示方法

IEEE浮点数表示利用了一种类似于科学计数法的表示方式来记录浮点数,也就是如下的形式
在这里插入图片描述
只要记录下s,M,E这三个数值,就可以确定的表示一个浮点数。
下面来分别解释这三个数字的含义:
在这里插入图片描述
这里0会特殊处理是指会分为正负0,后面我们再了解。
在这里插入图片描述
这个尾数类似于对于一个十进制科学技术法表示的数字 1.564 ∗ 1 0 6 1.564*10^6 1.564106中的1.564,会对这个数字有个范围限制。IEEE标准根据不同的情况,会限定尾数在不同的范围,以用作不同的功能。后面也会了解。
在这里插入图片描述

2.2 存储方式

在这里插入图片描述

  • 对于单精度浮点数,可以使用4个字节(32位)进行存储,也就是将s,exp,frac进行存储。这里的frac跟尾数M不是对等的,后面我们会看到区别。其存储空间划分分别为
    s1位,k = 8位,n = 23位。
  • 同样对于双精度浮点数,可以使用8个字节(64位)进行存储。其中s1位,k = 11位,n = 52位。
    在这里插入图片描述

2.3 浮点数数值的分类

给定位表示, 根据exp的值, 被编码的值可以分成三种不同的情况(最后一种情况有 两个变种)
在这里插入图片描述

1. 规格化的值

这是最普遍的情况。当exp的位模式既不全为0(数值0), 也不全为1(单精度数值为255, 双精度数值为2047 )时, 都属于这类情况。要记得,exp是用来表示2的幂的,也就是十进制科学计数法中10的幂的值。这是一个有符号整数,它的值不是从其位表示直接读取的,而是一种以偏置的形式表示的。意思是阶码的值E = e - Bias,其中e是阶码的位表示以无符号整数的形式读取的结果,Bias是一个等于 2 k − 1 − 1 2^{k-1} - 1 2k11(单精度是127,双精度是1023),这样我们就可以获得阶码的取值范围, 对于单精度是-126到+127, 而对于双精度是-1022到+1023。

就好像在十进制科学计数法中,我们要求尾数大于等于1小于10并且总能做到一样,我们同样要求尾数M大于1小于2(2就是二进制的“10”),这时我们可以把尾数M定义为 M = 1 + f。f为一个二进制小数。由于我们总可以将M表示成一个形如 1. f n − 1 f n − 2 . . . f 0 1.f_{n-1}f_{n-2}...f_0 1.fn1fn2...f0的数字,那么我们就可以省略记录开头的1,仅把f进行记录,这样可以获取一位额外的精度位。这种方式也叫做隐含的以1开头的表示

2. 非规格化的值

阶码域全为0的时候,所表示的数是非规格化的值。此时阶码的值为E = 1 - Bias(Bias与上面的一样),而尾数的值为M = f,不包含隐含的开头的1
这种记录方式有两个作用:

  1. 可以用来表示0,因为规格化的值M默认有一个开头的1,所以无法表示0。这时符号位为0,f为0的时候,M也等于0,该浮点数表示+0.0,同理符号位为1时表示-0.0。
  2. 可以用来表示那些非常接近0的数字,提供了一个逐渐溢出的属性。

使阶码值为1-Bias而不是简单的-Bias似乎是违反直觉的。在下一部分示例中可以看到, 这种方式提供了一种从非规格化值平滑转换到规格化值的方法。

3. 特殊值

最后一类数值是当指阶码全为1的时候出现的。

  • 小数域全为0时,得到的值表示无穷,当s=0时是正无穷, 当s=1时是负无穷。当我们把两个非常大的数相乘, 或者除以零时,无穷能够表示溢出的结果。
  • 当小数域为非零时, 结果值被称为“NaN", 即“不是一个数(Not a Number) " 的缩写。

在这里插入图片描述

3、数字示例

第一个例子展示了一组数,它们可以用假定的6位格式来表示, 有k=3的阶码位和n =2的尾数位。偏置量是 2 3 − 1 2^{3-1} 231-1 =3。最大数值的规格化数是+14 ,最小的为-14。非规格化数聚集在0的附近。
在这里插入图片描述
可以观察到,那些可表示的数并不是均匀分布的,越靠近
原点处它们越稠密。

第二组例子如下,其中有k=4的阶码位和n=3的小数位。偏置量是7。
在这里插入图片描述
可以观察到最大非规格化数5和最小规格化数之间的平滑转变。这种平滑性归功于我们对非规格化数的E的定义。通过将E定义为1 - Bias,而不是- Bias。
可以看到一个有趣的属性,假如将上图中的值的位表达式解释为无符号
整数,它们就是按升序排列的,就像它们表示的浮点数一样,负数也有类似的规律,可以利用这个特点对浮点数进行排序

1. 一个具体的转换例子

12345 其二进制表示为11000000111001,我们将把它转换成单精度形式。首先将这个数转换成规格化的表示, 12345 = 1.100000011100 1 2 ∗ 2 13 12345=1.1000000111001_2 * 2^{13} 12345=1.10000001110012213

  • 首先构造尾数M=1+f,作为一个规格化的数,丢弃开头的1,并在末尾增加10 个0, 来构造小数字段, 得到f的二进制表示[10000001110010000000000]。
  • 第二,构造阶码字段,E = e - Bias,所以e = E + Bias = 13 + 127 = 140,其二进制表示为[ 10001100 ]。
  • 第三,符号位0
    合在一起就是单精度浮点数[01000110010000001110010000000000]。
    我们对比一下单精度浮点数和整数表示的区别,发现*号的部分是一样的。
    在这里插入图片描述

4、舍入

由于表示方法的限制,浮点数只能近似的表示实数运算。
IEEE浮点格式定义了四种不同的舍入方式。默认的方法是找到最接近的匹配, 而其他三种可用于计算上界和下界。

四种舍入方式表示如上,其中向偶数舍入(也就是找到最接近的匹配,1.6最接近的整数是2,1.4最接近的整数是1)在确定两个可能结果中间数值时,将采取将数字向上或者向下舍入, 使得结果的最低有效数字是偶数。因此, 这种方法将1.5和2.5都舍入成2。

默认使用最接近的匹配,是为了减少对整个数据整体的影响。例如求平均值的时候,如果都是向上舍入,则平均数值一定会变高,默认的舍入方式可以尽可能减少影响

相似地,向偶数舍人法能够运用在二进制小数上。我们将最低有效位的值0认为是偶
数,值1认为是奇数。一般来说,只有形如XX …X.YY …Y100… 的二进制位模式的数,才会表示在两个可能的结果正中间的值。我们将 10.1110 0 2 10. 11100_2 10.111002 向上舍入成 11.0 0 2 11.00_2 11.002,而 10.1010 0 2 10.10100_2 10.101002向下舍入成 10.1 0 2 10.10_2 10.102 ,因为这些值是两个可能值的中间值,并且我们倾向于使最低有效位为零。

5、浮点运算

1、加法

  1. 可交换的
  2. 不可结合的
  • 原因:溢出和舍入
  • 举例:使用单精度浮点, 表达式(3. 14 +1e10) -1e10 求值得到0. 0。因为舍入,值3. 14会丢失。另一方面, 表达式3. 14+(1e10-1e10) 得出值3. 14。
  1. 加法逆元
    大多数值在浮点加法下都有逆元,无穷和NaN是例外情况。(正无穷加负无穷等于NaN,任何数加上NaN都等于NaN)

2、单调性

在这里插入图片描述

3、乘法

  1. 可交换
  2. 乘法单元为1.0
  3. 不可结合性(溢出或舍入的原因)
  4. 不具备在加法上的分配性(溢出或舍入的原因)

其实实际使用中,只要在浮点数范围内进行运算(也就是避免舍入和溢出),还是可以灵活使用浮点数的

6、C语言中的浮点数

C语言提供了两种不同的浮点数据类型:float和double。在支持IEEE浮点
格式的机器上.这些数据类型就对应单精度和双精度浮点。另外, 这类机器使用向偶数舍入的舍入方式。
C语言标准不要求机器使用IEEE浮点, 所以没有标准的方法来改变舍入方式或者得到诸如— 0、NaN之类的特殊值。大部分系统会提供.h头文件提供这些特征。

1.强制类型转换

当在int、float和double格式之间进行强制类型转换时, 程序改变数值和位模式
的原则如下(假设int是32位的):

  • 从int转换成float, 数字不会溢出,但是可能被舍入。
  • 从int或float转换成double, 因为double 有更大的范围(也就是可表示值的范
    围),也有更高的精度(也就是有效位数), 所以能够保留精确的数值。
  • 从double转换成float, 因为范围要小一些, 所以值可能溢出成无穷。另
    外, 由于精确度较小, 它还可能被舍入。
  • 从float 或者double转换成int, 值将会向零舍入。例如,1. 999将被转换成1 ,
    而-1. 999将被转换成-1。进一步来说, 值可能会溢出。C语言标准没有对这种情
    况指定固定的结果。与Intel兼容的微处理器指定位模式[10 … 00](字长为w时的
    TMinw )为整数不确定(integer indefinite)值。一个从浮点数到整数的转换, 如果不
    能为该浮点数找到一个合理的整数近似值, 就会产生这样一个值。因此, 表达式
    (int)+1e10会得到-21483648, 即从一个正值变成了一个负值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值