3

unsigned long long で奇妙な問題が発生しています。

unsigned long long を設定すると発生します (size_t を使用しましたが、問題は ull で再現可能です)。2^31 に設定しましたが、何らかの理由で 18446744071562067968、つまり 2^64 - 2^31 に戻ります。x64 コンパイルを使用していることに注意してください。

unsigned long long a = 1 << 31;
cout << a;

//Outputs 18446744071562067968, Expected 2147483648

ull の限界は 2^64-1 だと思いましたか? では、なぜ 2^31 を格納できないのでしょうか? 2^30 で十分です。Sizeof(a) は 8 を返します。これは、私の間違いでなければ 64 ビットであり、2^64-1 の制限を証明しています。

Visual C++ 2013 Express デスクトップでコンパイルしています。

私の唯一の推測は、通常の long 型に適合しないため、何らかのタイプのオーバーフロー エラーであるということです。

4

1 に答える 1

2

あなたが見ているのは、負の整数値が unsigned long long に割り当てられたときの符号拡張です。

これを修正するには、最初から値を unsigned にする必要があります。たとえば、次のようになります。

#include <iostream>
#include <iomanip>

int main()
{
    unsigned long long a = 1ull << 31ull;
    std::cout << a << "\n";
    std::cout << std::hex << a << "\n";

    return 0;
}

警告レベルが十分に高く設定されている場合 (/W4)、符号付き/符号なしの不一致に関する警告が表示されます。

完全にするために、両方の引数を修飾する必要はありません。左のオペランドだけで問題ないので、うまくいきますunsigned long long a = 1u << 31;。私はできるだけ明確にすることを好みます。

于 2014-06-01T02:33:30.583 に答える