2012-11-03 25 views
3

考虑两个以下的代码段 - 在它们之间的唯一区别是一个单一的COUT打印出值EPS:
http://ideone.com/0bEeHz - 这里的程序进入和无限循环由于COUT每股收益的变化值设为0最低双重正值 - 可以改变其价值?

#include <iostream> 

int main() 
{ 
    double tmp = 1.; 
    double eps; 
    while(tmp != 0) { 
     eps = tmp; 
     tmp /= 2.; 
    } 
    if(eps == 0) { 
     std::cout << "(1)eps is zero!\n"; 
    } 
    std::cout << "eps before: " << eps; 
    if(eps == 0) { 
     std::cout << "(2)eps is zero!\n"; 
    } 

    while(eps < 1.) { 
     tmp = eps; 
     eps *= 2.; 
     if(tmp == eps) { 
      printf("wtf?\n"); 
     } 
    } 

    std::cout << "eps after: " << eps; 
} 


http://ideone.com/pI4d30 - 这里我已经评论了cout。

#include <iostream> 

int main() 
{ 
    double tmp = 1.; 
    double eps; 
    while(tmp != 0) { 
     eps = tmp; 
     tmp /= 2.; 
    } 
    if(eps == 0) { 
     std::cout << "(1)eps is zero!\n"; 
    } 
    //std::cout << "eps before: " << eps; 
    if(eps == 0) { 
     std::cout << "(2)eps is zero!\n"; 
    } 

    while(eps < 1.) { 
     tmp = eps; 
     eps *= 2.; 
     if(tmp == eps) { 
      printf("wtf?\n"); 
     } 
    } 

    std::cout << "eps after: " << eps; 
} 


因此,一个单一的cout显着和令人惊讶的非常改变程序逻辑。这是为什么?

+1

我无法在G ++ 4.7上重现这一点 – Pubby

回答

2

我认为这是比所要求的第5(表达式)的情况下,第11段

浮动操作数的和的值可以以更高的精度和范围来表示浮动表达式的结果类型;类型不会因此而改变。

在工作,比照。 this variation的原始代码。

while(tmp != 0) { 
    eps = tmp; 
    tmp /= 2.; 
} 

计算和比较以扩展精度执行。循环运行直到eps是最小的正扩展值(可能是80位x87扩展类型)。

在扩展精度
if(eps == 0) { 
    std::cout << "(1)eps is zero!\n"; 
} 

尽管如此,eps != 0

std::cout << "eps before: " << eps; 

有关转换为字符串打印,eps被存储并转换为double精度,导致0

if(eps == 0) { 
    std::cout << "(2)eps is zero!\n"; 
} 

是, 现在它是。