何为浮点数
在大部分实现中,浮点数通常是基于IEEE浮点标准用V=(-1)的形式来表示一个数
- s是符号位,决定这个数是正数还是负数.
- significand M是一个二进制小数,范围在[1~ 2 -
]或者[0-
] 中文称为尾数.
- exponent E是对浮点数加权,权重是2的E次幂,中文称为码阶
将浮点数的位划分位3个字段,分别对这些值进行编码(encode value):
- 最高位的单独位s直接编码成符号s,0或者1,0表示正数,1表示负数
- k位的码阶字段集合exp=
编码阶码E
- n位小数字段frac=
编码尾数M,但是编码出来的值也依赖于解码的字段的值是否等于0
单精度浮点格式 s、exp、frac字段分别位1,8,23
双精度浮点格式 s、exp、frac字段分别位1,11,52
bit 分布如下:
根据exp的值,被编码的值可以分成3种不同的情况(最后一种有两个变种),已单精度举例:
- 情况1:规格化的值
这是最普遍的情况。当exp的位模式不全为0也不全为1时,都属于这种情况。在这种情况下阶码字段E= ,其中
是无符号数,其位表示为
,
(单精度是127,双精度是1023),由此计算出的E的范围在单精度下是[-126~127],在双精度下是[-1022~1023].
小数字段frac被解释为描述小数值 (
),其二进制表示为
.实数值=
尾数定义为
.
- 情况2:非规格化的值
当exp的位模式全为0时,在这种情况下,阶码 = -126,而尾数
,不包含隐含的开头1.为什么E没有=
,而是
,是为了从非规格化值平滑的转换到规格化值的方法.
非规格化的值有两个用途:
- 提供了一种表示0的方法,因为使用规格化数
,因此无法表示0.其中根据符号位不同,我们可以有
和
。根据IEEE浮点格式,两者某些方面被认为是不同的,而在其他方面是相同的
- 提供一个可以表示非常接近
的数.它提供了一种属性,称为逐渐溢出,其中可能的数值分布均匀地接近于
- 情况3:特殊值
当exp的位模式全为1时出现。当小数域全为0时,得到的值表示无穷,当时是
;当s=1时是
。当我们把两个非常大的数相乘,或者除以0时,无穷可以表示“溢出”的结果。当小数域为非零时,结果值被称为“NaN”,无效值(Not a Number的缩写)。比如当计算
时,也可用于表示未初始化的数据。
截图给出了一些边界值的构成,包括最大/小值,无穷值,0
舍入
由于实数表示的精度与范围的限制,浮点型只能近似的表示实数,因此对于值x,我们一般想用一种系统的方法,能够找到“最接近的”匹配值 ,
能够用期望的浮点形式表示出来。这就是舍入的运算任务。一个关键的问题是在两个可能值的中间如何确定舍入的方向。我们有4种舍入方式:
向零舍入方式把正数向下舍入,把负数向上舍入。
向下舍入方式把正数和负数都向下舍入
向上舍入方式把正数和负数都向上舍入
偶数舍入就是4舍5入,选择这种模式是因为在大多数现实情况种避免了求平均值的统计误差。
溢出
浮点型计算都是按照实数来进行,不像整数计算有正+正溢出的负的情况,当浮点计算溢出有两种情况:
- 向无穷大溢出:当求得的值大于浮点型能表示的最大值,就变为
,负无穷同理
- 向0溢出:当为正数时,当求得的值小于能表示的最小值时,舍入为0,
同理
计算法则
有别于整数运算,支持结合律,交换律,分配律。浮点型计算不支持结合律,就是说
与
,
求得的值可能是不一样的,虽然差异小的无关紧要,但是这妨碍的编译器的优化,结果是编译器倾向于保守,避免任何对功能产生影响的优化,即使是很轻微的影响。