STLにはvectorの各要素の数の和を出力するaccumulate()という便利関数があるが、気をつけないとオーバーフローによりはまってしまう。その例として以下のコードを見ていただきたい。コードの意図は、1000000000 + 1000000001 + ... + 1000000009を計算してsumに格納することである。
#include <iostream> #include <vector> #include <numeric> using namespace std; int main(){ vector<long long> nums; for(int i = 0; i < 10; ++i){ nums.push_back( (i + 1000000000) ); cout << nums[i] << endl; } long long sum = accumulate(nums.begin(), nums.end(), 0); cout << "-----" << endl; cout << "sum = " << sum << endl; return 0; }
しかしこのコードでは、意図に反して
----- sum = 1410065453 -----
という結果を出してしまう。
この原因は、accumulateの第三引数(数値の合計に下駄をはかせる値)に0と書いてしまったことにある。この0がint型とみなされるせいで、数列の和がint型で計算されてしまう。
意図通りに動かすには、accumulateの第三引数を0LLと書き、long long型の整数であることを明示する必要がある。
----- long long sum = accumulate(nums.begin(), nums.end(), 0LL); -----
このように修正することで、意図通りの結果が得られた。
----- sum = 10000000045 -----
修正後のコード全文はこちら。