我阅读了关于heisenbug的维基页面,但是不明白这个例子.任何人都可以详细解释一下吗?
heisenbug的一个常见示例是在使用优化编译器编译程序时出现的错误,但是在没有优化的情况下编译相同程序时则不会出现错误(通常是为了使用调试器进行检查).在调试时,优化程序通常保留在寄存器中的值通常会被推送到主存储器.例如,这可能会影响浮点比较的结果,因为存储器中的值可能比寄存器中的值具有更小的范围和精度.
Per*_*xty 10
这是最近发布的具体示例:
这是一个非常好的标本,因为我们都可以重现它:http://ideone.com/rjY5kQ
这些错误非常依赖于平台的非常精确的功能,人们也发现它们很难再现.
在这种情况下,当省略'打印输出'时,程序在CPU寄存器内执行高精度比较(高于存储在a中double).但是要打印出值,编译器决定将结果移动到主存储器,这会导致精度的隐式截断.当它使用截断值进行比较时,它会成功.
#include <iostream>
#include <cmath>
double up = 19.0 + (61.0/125.0);
double down = -32.0 - (2.0/3.0);
double rectangle = (up - down) * 8.0;
double f(double x) {
return (pow(x, 4.0)/500.0) - (pow(x, 2.0)/200.0) - 0.012;
}
double g(double x) {
return -(pow(x, 3.0)/30.0) + (x/20.0) + (1.0/6.0);
}
double area_upper(double x, double step) {
return (((up - f(x)) + (up - f(x + step))) * step) / 2.0;
}
double area_lower(double x, double step) {
return (((g(x) - down) + (g(x + step) - down)) * step) / 2.0;
}
double area(double x, double step) {
return area_upper(x, step) + area_lower(x, step);
}
int main() {
double current = 0, last = 0, step = 1.0;
do {
last = current;
step /= 10.0;
current = 0;
for(double x = 2.0; x < 10.0; x += step) current += area(x, step);
current = rectangle - current;
current = round(current * 1000.0) / 1000.0;
//std::cout << current << std::endl; //<-- COMMENT BACK IN TO "FIX" BUG
} while(current != last);
std::cout << current << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑:已验证的错误和修复仍然展示:20-Feb-17