2012-11-15 37 views
-2

我不知道爲什麼,如果我有以下代碼:ç開方==長詮釋

int main() { 
    long int height_cat, number_worker_cats, number_helper_cats, height_tree; 
    bool flag; 
    scanf("%ld%ld", &height_cat, &number_worker_cats); 
    for (number_helper_cats = 1; ; ++number_helper_cats) { 
     for (height_tree = 1; (long int)pow(number_helper_cats + 1, height_tree) <= height_cat; ++height_tree) { 
      if ((long int)(pow(number_helper_cats + 1, height_tree) - height_cat) == 0 && (long int)(pow(number_helper_cats, height_tree) - number_worker_cats) == 0) { 
       flag = true; 
       break; 
      } 
     } 
     if (flag) { 
      break; 
     } 
    } 
printf("%ld, %ld\n", number_helper_cats, height_tree); 
} 

我在尋找number_helper_catsheight_tree(number_helper_cats +1)^height_tree = height_catnumber_helper_cats^height_tree = number_worker_cats其中height_catnumber_worker_catsintegers

例如,如果height_cat = 216number_worker_cats = 125,代碼將停止number_helper_cats = 5height_tree = 3因爲(5+1)^3 = 2165^3 = 125

但是,如果我有下面的代碼它不工作,永遠循環,爲什麼?

int main() { 
    long int height_cat, number_worker_cats, number_helper_cats, height_tree; 
    bool flag; 
    scanf("%ld%ld", &height_cat, &number_worker_cats); 
    for (number_helper_cats = 1; ; ++number_helper_cats) { 
     for (height_tree = 1; pow(number_helper_cats + 1, height_tree) <= height_cat; ++height_tree) { 
      if ((long int)(pow(number_helper_cats + 1, height_tree)) == height_cat && 
         (long int)(pow(number_helper_cats, height_tree)) == number_worker_cats) { 
       flag = true; 
       break; 
      } 
     } 
     if (flag) { 
      break; 
     } 
    } 
printf("%ld, %ld\n", number_helper_cats, height_tree); 
} 

一切都是long int和每height_cat以及用於測試用例number_worker_cats爲真用於操作另一個例子height_cat = 5764801,number_worker_cats = 1679616,number_helper_cats = 6和height_tree = 8,因爲(6 + 1)^ 8 = 5764801 ,6^8 = 1679616.但第一個代碼運行良好,第二個代碼永遠循環。 pow are precise我的意思是6^3 = 216和5^3 = 125對不對? :p

+3

至少告訴我們哪個迴路是無限的。我敢打賭,一旦你明白了這一點,你就會知道答案。 – MSalters

+0

@MSalters看起來很清楚(我認爲無論如何),外層循環是永遠的循環:一旦你打到一定數量的幫貓,內層循環甚至不會迭代,從而防止設置標誌。 –

+0

代碼(以及我不得不添加一堆樣板來編譯它)在g ++ 4.5和沒有優化,'-O2','-O3',甚至是-O3 -ffast-math'的情況下終止。請給我們一個完整的例子,我們可以編譯和運行以展示問題以及您所在的編譯器和體系結構。 –

回答

1

pow的結果是doubledouble數字在許多情況下不準確。爲了測試用double平等,常用的方法是

if (abs(pow(number_helper_cats + 1, height_tree) - height_cat)) < 0.001); // 0.001 is an arbitrary small number 
{ 
    ... 
} 

A和測試爲<=,你應該使用pow(number_helper_cats + 1, height_tree) <= height_cat + 0.001

但是,我必須提到,你的代碼不能在你的問題中提到你用gcc 4.7.2提到的無限循環。你所有的循環都正常結束。

+2

「雙數不會精確」。這顯然是不真實的。特別是'double(216)'和'double(125)'精確。如果有的話,'pow()'不準確,但即使這會讓我感到驚訝。 – MSalters

+1

實際上'double'可以表示各種各樣的整數值。在不知道投入的情況下,很難說這是否是問題。 –

+0

@ MSalters嗯,我在這裏發表了一個強烈的聲明,我會試着重述它。但我確實相信pow不會產生精確的結果,因爲它不應該爲ingtegers寫一個特殊的算法。 – fefe