質問タイトルが読み取ると、2^31を符号付きおよび符号なし32ビット整数変数に割り当てると、予期しない結果が得られます。ここで符号なしおよび符号なし32ビット整数変数に2^31を代入した後の奇妙な結果
は、私は何が起こっているのか確認するために作られた、(C++
中)のショートプログラムです:
#include <cstdio>
using namespace std;
int main()
{
unsigned long long n = 1<<31;
long long n2 = 1<<31; // this works as expected
printf("%llu\n",n);
printf("%lld\n",n2);
printf("size of ULL: %d, size of LL: %d\n", sizeof(unsigned long long), sizeof(long long));
return 0;
}
ここでは出力です:
MyPC/# c++ test.cpp -o test
MyPC/# ./test
18446744071562067968 <- Should be 2^31 right?
-2147483648 <- This is correct (-2^31 because of the sign bit)
size of ULL: 8, size of LL: 8
私はそれに、別の機能p()
を追加しました:
void p()
{
unsigned long long n = 1<<32; // since n is 8 bytes, this should be legal for any integer from 32 to 63
printf("%llu\n",n);
}
コンパイルと実行時に、これは混乱しますさらに私はさらに:
コンパイラは左シフトカウントが大きすぎると不満を持ちますか? sizeof(unsigned long long
)は8を返します。したがって、2^63-1はそのデータ型の最大値です。
それは多分、N * 2とn < < 1、常に同じように動作し、私はこの試みたしていないことを私を襲った:これは、のように2^63の正確な値を与える
void s()
{
unsigned long long n = 1;
for(int a=0;a<63;a++) n = n*2;
printf("%llu\n",n);
}
を出力は9223372036854775808
です(私はそれをpythonで検証しました)。しかし、左のたわごとをして何が間違っていますか?ウィキペディア
値がオーバーフローされていない -
(値がオーバーフローしない提供)
nだけ左シフト演算が2 N を乗算と等価です値が2^63(すべてのビットが設定されている)なので、マイナス記号だけが表示されます。
私はまだ左シフトで何が起こっているのか理解できません。だれでも説明してください。
PS:(それは場合に役立ちます)このプログラムは、このライン上でLinuxのミントを実行している32ビットシステムで
を使用これは、長い 'unsigned long型のn = 1ULL << 31でなければなりません;' – kirilloid
神!これは簡単でしたか?なぜ私はそれを考えなかったのですか?とにかく、はい1ULL << 31は動作します。ほんとありがと! – Rushil