- ベストアンサー
C言語
【プログラム】 #include<stdio.h> int main (void) { int i,n; long a; scanf("%d",&n); a=1; for(i=1;i<=n;i++){ printf("%3d回目 %12ld\n",i,a); a=a*2; } return 0; 【実行結果】("33"と入力) 33 1回目 1 2回目 2 3回目 4 4回目 8 : : : : 31回目 1073741824 32回目 -2147483648 33回目 0 【質問】 2倍していくと、32回目に負の数になり さらに33回目には0になりました。 こうなる理由を教えてください。 私は高2です。 出来ればわかりやすくお願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
long intのビット数は32bitです(OSにもよりますが) 32ビットは二進数で表すと、1が32個並びます。 またunsigedではない、整数の型では一番上のビットは2の補数として用いられます。 つまり整数で表されるのは、1が31個並んだ状態となります。 2進数を10進数で表すと 00000000000000000000000000000001→1 00000000000000000000000000000010→2 00000000000000000000000000000100→4 00000000000000000000000000001000→8 ・ ・ ・ 01000000000000000000000000000000→1073741824 上記のように1を倍々にしていくと左にシフトしていくことがわかります。 32回めでマイナスになる理由ですが、先ほど書いたように一番左は2の負数なので、ここが1であればマイナスになります。 また負の数はビットが逆転しますので下記の計算どおりです。 10000000000000000000000000000000→-2147483648 33回目ですが、さらに1を左シフトすると、範囲から消えてしまいます。 つまり 00000000000000000000000000000000→0 となるのです。
その他の回答 (1)
- SAKENOSAKA
- ベストアンサー率32% (78/240)
有効桁数と符号bitが関連します。 long a; をint(は同じかもしれませんが)やshort に変更して実行すると分かるように 扱える値が桁あふれしていることが原因です。 longといえども(2の31乗-1)以上の値を扱うことは出来ません。 (負数を除いたunsined longだと2の32乗-1まで扱えます。) 負数になるのは符号ビットである 先頭のbitが1に反転してしまうので 表示上では負数と認識してしまいます(不正なデータ) 完全に桁あふれして0になったあとは 0に何をかけても0が続きます。