2012-11-15 33 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