无法理解这两个代码示例之间的区别

时间:2014-07-05 14:00:41

标签: c++

我想编写一个程序来计算由n行组成的区域数。 第一个例子是我的代码,第二个例子是我朋友的代码。我认为他们正在尝试做同样的事情,但对于n = 65535的情况,我的代码给了我错误的答案。我的代码中的问题在哪里?

我的代码:

#include<iostream>
using namespace std;

int main()
{
    int n;
    cin >> n;

    unsigned long long ans;
    ans = (n*(n + 1) / 2) + 1;
    cout << ans << endl;

    return 0;
}

我朋友的代码:

#include <iostream>

using namespace std;

int main(void){
double n,sum;
cin>>n;
sum=n*(n+1)/2+1;
cout<<(long)sum<<endl;
return 0;
}

2 个答案:

答案 0 :(得分:4)

在您的代码中:

int n;
ans = (n*(n + 1) / 2) + 1;

计算中的所有值都是整数:n声明为int,普通整数常量也是整数。因此,此计算的结果也将是int。您稍后将此结果分配给long long变量的事实不会改变这一点。

现在乘法65535 * 65536的结果不适合32位有符号int,所以你得到一个无意义的答案。通过使n长64位来修复程序。

答案 1 :(得分:4)

正如@Dithermaster建议的那样,这里的问题可能是整数溢出。

现在看来,你的代码实际上没有多大意义。特别是,由于您已将n定义为int,并且表达式中的所有整数文字:(n*(n + 1) / 2) + 1也足够小以适合int,计算将在int s上进行,然后(计算完成后),结果将转换为long long并分配给ans(因为您已将ans定义为long long)。

您几乎肯定想要的是在long long上执行整个计算以避免溢出。最明显的方法是将n定义为long long而不是int

您的朋友通过将n定义为double来避免这种情况。这一点起作用 - double的典型实现具有53位有效数,因此它可以(基本上)用作53位整数类型。这显然比int强制要求的16位要多得多,但同样明显低于long long规定的64位。

支持n为否定也没有意义,因此您可以考虑将nans定义为unsigned long long