对this answer的讨论让我想到了浮点数的等同性和等价性。我知道浮点数不能准确表示。问题是,在使用浮点算术时,是否有数学上等价的表达式会产生不同的结果?你能提供一个例子吗?等效表达式可以产生不同的浮点结果吗?
编辑:让我更清楚。我知道,使用不同编译器或不同机器的相同代码可能会返回不同的结果。我在寻找的是两个数学上相当的表达式,我可以在我的Python解释器/ C++程序中比较/无论如何得到意想不到的结果。
对this answer的讨论让我想到了浮点数的等同性和等价性。我知道浮点数不能准确表示。问题是,在使用浮点算术时,是否有数学上等价的表达式会产生不同的结果?你能提供一个例子吗?等效表达式可以产生不同的浮点结果吗?
编辑:让我更清楚。我知道,使用不同编译器或不同机器的相同代码可能会返回不同的结果。我在寻找的是两个数学上相当的表达式,我可以在我的Python解释器/ C++程序中比较/无论如何得到意想不到的结果。
在那里数学上等价 表达式将使用浮点时产生不同的结果算术?
绝对。事实上,你应该预料到这种情况会发生得更多。
即使在不同的机器或编译器上使用相同的代码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);
}
}
是的,比较
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,编译器,编译器开关,数学库等不同的结果
我会用乘法和加法尝试:
伪-c代码
float x = 1/7;
float y = x * 4;
float z = x + x + x + x;
if (y != z) {
printf("oh noes!\n");
}
您是否真的尝试过? – 2010-11-16 10:24:54
不,它可能只适用于某些带有特定优化标志的编译器。 – 2010-11-16 10:29:32