整数溢出问题

时间:2015-07-09 22:35:37

标签: c++

vector<int> getRow(int rowIndex) {
vector<int> result;
if(rowIndex < 0)   return result;
if(rowIndex == 0){
    result.push_back(1);
    return result;
}
for(int i = 0; i < rowIndex+1; i++){
    if(i == 0)  result.push_back(1);
    else{
        result.push_back(result[i-1] * (rowIndex+1-i)/i);
    }
}
return result;
}
int main()
{
    vector<int> tmp = getRow(30);
    for(int i = 0; i < tmp.size(); i++){
        cout << tmp[i] << " ";   
    }
    cout << endl;
    return 0;
}

这是来自LeetCode的Pascal的三角形编码问题,它要求输出Pascal三角形的第n行。使用rowIndex=30,输出如下:

1 30 435 4060 27405 142506 593775 2035800 5852925 14307150 30045015 54627300 86493225 119759850 145422675 -131213633 -123012780 -101304642 -73164463 -46209134 -25415023 -12102391 -4950978 -1722079 -502273 -120545 -23181 -3434 -367 -25 0 

显然,存在溢出问题。现在要解决此问题,我将行result.push_back(result[i-1] * (rowIndex+1-i)/i);修改为result.push_back((double)result[i-1] * (double)(rowIndex+1-i)/i);。它产生正确的输出:

1 30 435 4060 27405 142506 593775 2035800 5852925 14307150 30045015 54627300 86493225 119759850 145422675 155117520 145422675 119759850 86493225 54627300 30045015 14307150 5852925 2035800 593775 142506 27405 4060 435 30 1 

有人可以解释一下究竟是什么问题吗? 我们知道有符号整数值的范围是-2147483648到2147483647.没有强制转换,为什么值155117520打印为溢出-131213633

1 个答案:

答案 0 :(得分:3)

我是表达式

result[i-1] * (rowIndex+1-i)/i

首先进行乘法,然后导致溢出:

result[i-1] * (rowIndex + 1-i)

然后结果除以i,产生负输出。

顺便说一句,如果您决定投射,请避免由于可能的舍入问题而投射到double。你可以试试long,但最好在第一时间使用

vector<long>

甚至

vector<unsigned long>

或者,感谢 @WorldSEnder

vector<unsigned long long>

但请注意,该标准并不保证longlong long长于int。它既不保证int[-2147483648, 2147483647]范围内。

相关问题