代码之家  ›  专栏  ›  技术社区  ›  Björn Pollex

等价表达式能否产生不同的浮点结果?

  •  1
  • Björn Pollex  · 技术社区  · 14 年前

    讨论对象 this answer 刚刚让我想到浮点数的相等性和等价性。我知道浮点数不能总是准确表示。问题是,在使用浮点运算时,是否有数学上等价的表达式会产生不同的结果?你能举个例子吗?

    编辑: 让我更清楚一点。我知道,使用不同编译器或不同机器的相同代码可以返回不同的结果。我要找的是两个数学等价的表达式,我可以在Python解释器/C++程序中进行比较,得到一个意想不到的结果。

    3 回复  |  直到 14 年前
        1
  •  3
  •   Michael Borgwardt    14 年前

    在数学上有等价物吗 会产生不同结果的表达式 使用浮点时的结果 算术?

    当然。事实上,你应该期望这种情况经常发生。

    即使是相同的代码 can yield different results 在不同的机器或编译器上。

    你能举个例子吗?

    当然。这个Java代码应该重复地产生两个不同的结果:

    public strictfp class Test {
        public static void main(String[] args) throws Exception {
            float a = 0.7f;
            float b = 0.3f;
            float c = 0.1f;
    
            float r1 = ((a * b) * c);
            float r2 = (a * (b * c));
    
            System.out.println(r1);
            System.out.println(r2);
        }
    }
    
        2
  •  2
  •   Paul R    14 年前

    是的,比较例如

    x = (a * b) / c;
    

    具有

    x = a * (b / c);
    

    下面是C中的一个示例,它演示了这一点:

    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
        double a, b, c, x1, x2;
    
        a = sqrt((double)rand());
        b = sqrt((double)rand());
        c = sqrt((double)rand());
    
        x1 = (a * b) / c;
        x2 = a * (b / c);
    
        printf("a = %.20f\n", a);
        printf("b = %.20f\n", b);
        printf("c = %.20f\n", c);
        printf("x1 = %.20f\n", x1);
        printf("x2 = %.20f\n", x2);
        printf("x1 - x2 = %.20f\n", x1 - x2);
    
        return 0;
    }
    

    对于我来说,这给出了以下结果:

    $ gcc -O3 -Wall math.c -o math
    $ ./math
    a = 129.64181424216494065149
    b = 16807.00000000000000000000
    c = 40282.13093916457728482783
    x1 = 54.09073256970189902404
    x2 = 54.09073256970190612947
    x1 - x2 = -0.00000000000000710543
    $ 
    

    (核心i7、GCC 4.0.1、Mac OS X 10.6)

    注意,一般来说,任何给定的表达式和不同的CPU、编译器、编译器开关、数学库等都可能得到不同的结果。

        3
  •  0
  •   G B    14 年前

    我试着用乘法和加法:

    伪C码

    float x = 1/7;
    float y = x * 4;
    float z = x + x + x + x;
    if (y != z) {
        printf("oh noes!\n");
    }