美文网首页
IEEE浮点表示-StackOverflow

IEEE浮点表示-StackOverflow

作者: AwesomeAshe | 来源:发表于2016-03-15 15:48 被阅读67次

促使我在看这个问题也是stackoverflow的一个问题:
gcc为什么不优化aaaaaa为(aaa)*(aaa)
楼主的意思是向这种偶数次的幂运算,我们这样只做一半的浮点乘法不是更快吗?

对啊,我也觉得呢。。

下面就有人指出了:

Because Floating Point Math is not Associative. The way you group the operands in floating point multiplication has an effect on the numerical accuracy of the answer.
As a result, most compilers are very conservative about reordering floating point calculations unless they can be sure that the answer will stay the same, or unless you tell them you don't care about numerical accuracy. For example: the -fassociative-math
option
of gcc which allows gcc to reassociate floating point operations, or even the -ffast-math
option which allows even more aggressive tradeoffs of accuracy against speed.

Lambdageek correctly points out that because associativity does not hold for floating-point numbers, the "optimization" of aaaaaa to (aaa)(aaa)may change the value.

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

把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位扩展精度格式。
这意味着在寄存器中存储一个值,就会在读进读出的时候产生舍入,溢出,数字的值会被改变。

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

相关文章

  • IEEE浮点表示-StackOverflow

    促使我在看这个问题也是stackoverflow的一个问题:gcc为什么不优化aaaaaa为(aaa)*(aaa)...

  • PHP浮点数精度问题

    PHP常见的浮点数“bug” 浮点数的表示形式 浮点数的表示(IEEE 754): 浮点数, 以64位的长度(双精...

  • IEEE 754 浮点类型表示

    1.前言 看了很多IEEE 754,死脑筋,老是忘,这次就详细记下来,同时分享下浮点类型各种处理方式 2.综述 介...

  • 理解C语言浮点数的存储

    IEEE-754标准 目前世界上使用最为广泛的小数表示方法是浮点数表示法,而浮点数通用的算术标准是IEEE-754...

  • IEEE浮点数表示

    该文主要介绍一个浮点数在计算机中的表示,属于很底层的知识点 介绍计算机如何表示浮点数之前,先了解一下日常生活中,我...

  • IEEE浮点数表示

    IEEE标准中浮点数用形如V=(-1)^s x M x 2^E的格式表示一个小数:s☞符号位,s=1代表负数,s=...

  • Java 中 float 类型的内存结构分析

    前言 本文按照以下顺序讲解: 浮点数 IEEE 754定义的浮点数表示法 float 的最大值分析 题目分析 浮点...

  • 深入浅出iOS浮点数精度问题 (上)

    目录 一,浮点数精度丢失? 二,整数的二进制表示 三,浮点数的二进制表示 四,iEEE 754浮点数的手动转换 五...

  • 该死的IEEE-754浮点数,说「约」就「约」,你的底线呢?以J

    IEEE 754 表示:你尽管抓狂、骂娘,但你能完全避开我,算我输。 一、IEEE-754浮点数捅出的那些娄子 首...

  • IEEE754表示浮点数

    组成 IEEE754标准包含一组实数的二进制表示法。它有三部分组成: 符号位 指数位 尾数位 三种精度的浮点数各个...

网友评论

      本文标题:IEEE浮点表示-StackOverflow

      本文链接:https://www.haomeiwen.com/subject/kzxqlttx.html