该循环如何打印正确的语句然后错误地评估它?

时间:2014-12-18 06:15:18

标签: c++ algorithm

我写了这个小函数,它将取整数 k ,并返回产品:

2(0)+1 2(1)+1 2(2)+1 .. .2n + 1 ||对于n = 0,n <(k / 2)-1 如果 k 是偶数,(或0,我不确定技术上是零是偶数)如果k是奇数则为0。

这是一个更大的项目的一部分,但我能够将问题与这个功能隔离开来,我把它拉出来试图弄清楚发生了什么。这是我的功能。

double Product_2np1(int k)
 {
    int prod = 1;
    if(k % 2 == 0)
      {
       for(int n = 0; n <(k/2);n++){
       prod = prod * ((2*n)+ 1);
      }
      return prod;
    }else return 0;
 }


int main(){
    for(int i=0; i<5;i++)
       {
         std::cout <<"k= " << i<< "==>" << Product_2np1(i) << std::endl;
       }
return 0; 
}

输出:

  • k = 0 ==&gt; 2.64619e-260
  • k = 1 ==&gt; 0
  • k = 2 ==&gt; 2.64619e-260
  • k = 3 ==&gt; 0
  • k = 4 ==&gt; 2.64619e-260
  • k = 5 ==&gt; 0

现在这对我来说是无稽之谈,所以我回到了函数中并投入了一些打印件以查看发生了什么。将Product_2np1更改为此:

double Product_2np1(int k)
 {
    int prod = 1;
    if(k % 2 == 0)
      {
       for(int n = 0; n <(k/2);n++){
       std::cout << "(2*" << n << ")+ 1)" <<std:endl;
      }
      return 1;
    }else return 0;
 }

并且主要我只有k = 4案例评估:

int main(){
     Product_2np1(4);
return 0; 
}

这给了我输出:

  • 2(0)1
  • 2(1)1

使用我方便的TI-86我打了一拳,以确保我没有失去它,我得到了

  • 2(0)+1 = 0 + 1 = 1
  • 2(1)+1 = 2 + 1 = 3

并将它们相乘应该给我3,而不是2.64619e-260。

所以我不得不问你们这里有什么可能发生的事情?

1 个答案:

答案 0 :(得分:0)

问题是您的数据类型 - 您的函数double Product_2np1(int k)返回doubleprodint。我不知道你使用的是哪个编译器(也许是Turbo C) - 但是你应该至少得到一个警告。通常类型转换从较小到较大 - 因此认为这里的结果是未定义的 - 请参阅此Sample on Ideone。问题是我们正在尝试从int强制转换为double,这就是问题所在。

#include <cstdio>

int main()
{
    printf("%lf", 2);
    printf("\n%lf", 2.0);
    return 0; 
}

输出:

Success time: 0 memory: 3340 signal:0
0.000000
2.000000

从C标准(1999):
6.3.1.4实际浮动和整数

  

1当实数浮点类型的有限值转换为整数时   除了_Bool之外的类型,小数部分被丢弃(即,   值被截断为零)。如果是积分部分的值   不能用整数类型表示,行为是未定义的。

来自C ++标准(2003):

  

4.9浮动积分转换[conv.fpint] 1浮点类型的右值可以转换为整数类型的右值。   转换截断;也就是说,丢弃小数部分。   如果无法表示截断值,则行为未定义   在目的地类型中。 [注意:如果目的地类型是bool,请参阅   4.12。 ]