1. ホーム
  2. c++

[解決済み] なぜか出る。-9223372036854775808

2022-02-01 04:01:12

質問

#include <iostream>
#include <sstream>
#include <numeric>
#include <math.h>

using namespace std;

int64_t splitAdd(int64_t value) {
    ostringstream intStream;
    intStream << value;
    string intString(intStream.str());
    return accumulate(intString.begin(), intString.end(), 0) - (intString.size() * int64_t('0'));
}

int main(int argc, char *argv[]) {
    int64_t maxPower = 50;
    int64_t results[maxPower];
    for (int64_t tuple = 0; tuple <= maxPower; tuple++) {
        for(int64_t power = 0; power <= maxPower; power++) {
            int64_t value = pow(tuple, power);
            while (value > 9) {
                value = splitAdd(value);
            }
            results[power] = value;
        }
        cout << tuple << endl;
        for (int i = 0; i < maxPower; i++) {
            cout << results[i] << ',';
        }
        cout << endl;
    }
}

しばらくすると、「-9223372036854775808」という値が繰り返し表示されます。私はこれをコードランナー2でも実行していますが、それが違いを生むかどうかはわかりません。

解決方法は?

目に余るエラーはこれだ。

int64_t maxPower = 50;
int64_t results[maxPower];  // <-- Not really legal, but let's pretend
//...
for (int64_t power = 0; 
             power <= maxPower; // <-- Look at the loop constraints
             power++) 
{  
    //....
}
results[power] = value;  // <-- Buffer overrun

以降 maxPower が50であれば、境界外の要素にアクセスしていることになります。 これは 未定義の動作

また、コードを合法的なC++にするために、50の配列を宣言するか。

int64_t results[50];

を宣言するか std::vector<int64_t> .

そうして at() の代わりに [] そうすれば、プログラムがどのように壊れるか、よりよくわかるようになります。 参照 std::vectorを使用したライブサンプルはこちら .


奇数(quot;odd number")の件ですが、ここで数値のオーバーフローが発生しています。

int64_t value = pow(tuple, power);

もし tuple が3であり、かつ power41 をオーバーフローしている場合、その値は int64_t の型があります。

もしかしたら 任意精度ライブラリ (できれば必要な数学演算子がオーバーロードされているもの)、あるいは自分で書いて、quot;regular" C++の型を使う代わりにします。 そうすれば、オーバーフローは起こらないし、起こすべきではないでしょう。