2012-11-03 24 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"; 
} 

是, 現在它是。