搜索
您的当前位置:首页正文

IEEE浮点表示-StackOverflow

来源:二三娱乐

对啊,我也觉得呢。。

下面就有人指出了:

就像我下面会介绍的一样,浮点运算实际上是一个很复杂的东西,首先浮点数并不精确,只是用近似值去代替;
其次浮点运算里面会发生溢出,舍入的情况,导致出现意想不到的结果。

把aaaaaa优化为(aaa)*(aaa)就有可能会出错哦,所以编译器还是采取稳妥一点的思路比较好。

然后还有人补充了,即使是普通的加法运算,编译器也不会利用加法的结合性去优化(这一点下面也提到了),通俗的解释就是“大数吃小数”。

Another similar case: most compilers won't optimize a + b + c + d
to (a + b) + (c + d)
(this is an optimization since the second expression can be pipelined better) and evaluate it as given (i.e. as (((a + b) + c) + d)
). This too is because of corner cases:
float a = 1e35, b = 1e-5, c = -1e35, d = 1e-5; printf("%e %e\n", a + b + c + d, (a + b) + (c + d));
This outputs 1.000000e-05 0.000000e+00

IEEE浮点表示:

使用如下形式:


浮点表示
  • 符号s(sign)表示符号
  • 有效数significand M是一个二进制小数,它的范围在1-2间或0-1间
  • 指数exponent E是2的幂(可以是负数)
    浮点数的位被划分为三个域,以编码这些值:
  • 一个单独的符号s位直接编码s
  • k位的指数域


    指数域

    编码指数E

  • n位小数域


    小数域

    编码有效数M

在floate中,s,exp,frac分别为 1位,k=8位,n=23位
在double中,s,exp,frac分别为 1位,k=11位,n=52位

c语言中的浮点类型强制转换:

溢出与范围有关,舍入与精度有关

int->float 数字不会溢出,可能被舍入
int/float->double double范围大,所以会被精确的保留
double->float 可能溢出位无穷大,还可能被舍入
float/double->int 值向0截断,比如1.999变为1;还可能会溢出

在Intel处理器的计算机中,由于处理器内部含有寄存器,而浮点寄存器使用特殊的80位扩展精度格式。
这意味着在寄存器中存储一个值,就会在读进读出的时候产生舍入,溢出,数字的值会被改变。

使用浮点运算的时候要小心,因为浮点运算的范围和精度有限,而且浮点运算不遵守普遍的算术属性,比如结合性。

Top