IEEE754标准

1.IEEE754标准起源

IEEE 754由1985年电子与电气工程师协会IEEE制定,用以表示浮点数的格式,包括0INFNAN等,以及这些数值的浮点数运算符。标准的指定便于不同处理器之间程序的移植及研制更为复杂的数值运算程序等。

2.IEEE754规定

  • 尾数原码表示,小数点前隐含一个1
  • 基值隐含为2
  • 阶码移码表示,移码的偏移值有专门约定,n位移码的偏移值为011111112^{n-1}-1
  • 阶码的最大值、最小值作为特殊标记预留,用来标记某些异常事件或机器
  • 单精度、双精度;单精度扩展、双精度扩展。

3.单精度浮点数float(32bit)的表达形式


由于尾数存在一个隐含的1,尾数的数值位相当于多表示了1位,且节省了存储空间。

4.IEEE754特殊标记

IEEE754有别于一般的移码偏移量(2^{n-1})设计,而是采用2^{n-1}-1,这样设计可以使得正数多表示一个数。在8位移码的情况下所能表示的范围是-127~128,其中0000000011111111用来做特殊标记。

  • 移码为00000000时,表示非规格化尾数,此时小数点前没有隐含的1,且指数固定为-126
  • 移码为11111111时,表示INF和NAN。例如尾数数值部分全为0,则表示INF(根据符号位决定正负),其余情况则为NAN。

5.IEEE754下溢处理

假设尾数的数值位有3位,移码有3位,现有x = 1.011×2^{-1}, y = 1.001×2^{-1}
若执行以下代码

if(x - y == 0)
  cout << "x == y" << endl;
else
  cout << "x != y" << endl;

我们先口算以下减法的结果是0.010×2^{-1},即1.000×2^{-3},显然-3的移码为000,这是特殊标记,且尾数数值部分全0,则表示+0,从而会导致上述代码输出“x == y”,为了避免逻辑错误,IEEE754的解决方法是渐进下溢,用非规格化浮点数来表示接近0但不等于0的数,即将上例转化为0.100×2^{-2},这样就能用非规格化浮点数表示接近0的数了,避免出现逻辑错误。

6.IEEE754舍入模式

  • 就近舍入:舍入到最接近的可表示值;当有两个最接近的可表示值时,首选“偶数”值。
  • 朝0舍入
  • 朝+\infty舍入
  • 朝-\infty舍入

7.浮点数精度不足所带来的错误

首先来看这样一段代码

#include <stdio.h>

int main(){
  float f = 123456789;
  printf("%f\n", f);
  return 0;
}

我们预期的执行结果是123456789.000000,但实际上结果是这样的

123456792.000000

显然前7位是对的,问题出在浮点数的精度上,单精度浮点数尾数数值位有23位,再加上隐含的1,共计24位,而代码中定义的变量f是用10进制表示的,那么24位2进制能表示多少位10进制呢,答案是24lg2向下取整7,这样就能解释为什么执行结果的前7位是正确的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容