2

重複の可能性:
int を unsigned int で割るとロールオーバーが発生する

こんにちは私は次のことをしています:

struct coord{
    int col;

};


int main(int argc, char* argv[]) {

    coord c;
    c.col = 0; 

    std::vector<coord> v;

    for(int i = 0; i < 5; i++){
        v.push_back(coord());
    }

    c.col += -13;


    cout << " c.col is " << c.col << endl;
    cout << " v size is " << v.size() << endl;

    c.col /= v.size();


    cout << c.col << endl;

}

次の出力が得られます。

 c.col is -13
 v size is 5
858993456

ただし、分割線を次のように変更するc.col /= ((int)v.size());と、期待される出力が得られます。

 c.col is -13
 v size is 5
-2

どうしてこれなの?

4

4 に答える 4

5

これはである結果v.size()ですunsigned

intをunsignedintで割ってロールオーバーを引き起こすを参照してください

于 2013-01-10T10:29:44.487 に答える
4

問題は、整数型の場合はを返すことですvector< ... >::size()。明らかに、符号付き整数を符号なし整数で除算すると問題が発生します。size_ttypedefunigned

于 2013-01-10T10:28:50.863 に答える
2

std :: vector :: sizeは、符号なし整数型、通常はunsignedintであるsize_tを返します。intunsignedintを使用して算術演算を実行すると、intオペランドがunsignedintに変換されて演算が実行されます。この場合、-13はunsigned intに変換されます。これは、4294967295(16進数のFFFFFFFF)に近い数値です。そしてそれは5で割られます。

于 2013-01-10T10:37:49.353 に答える
1

前述のように、その理由は、最初に符号付きの値を符号なしに変換することによって、符号付き/符号なしの除算が実行されるためです。

そのため、符号なしの値を符号付きの型に手動で変換して、これを防ぐ必要があります。

v.size()には大きすぎるリスクがありintます。しかし、被除数に収まるのでint、除数がそれよりも大きい場合、除算の結果はかなり退屈です。したがって、2 の補数でパディング ビットがないと仮定すると、次のようになります。

if (v.size() <= INT_MAX) {
    c.col /= int(v.size());
} else if (c.col == INT_MIN && v.size() - 1 == INT_MAX) {
    c.col = -1;
} else {
    c.col = (-1 / 2);
}

C++03 では、負の値をより大きな正の値で割った値が 0 か -1 かは実装定義であるため、面白い(-1 / 2). C++11 では、0 を使用できます。

2 の補数以外の表現をカバーするには、特殊なケースを別の方法で処理する必要があります。

于 2013-01-10T11:34:11.620 に答える