• ベストアンサー

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です。 出来ればわかりやすくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • tryouts
  • ベストアンサー率31% (126/404)
回答No.1

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)

回答No.2

有効桁数と符号bitが関連します。 long a; をint(は同じかもしれませんが)やshort に変更して実行すると分かるように 扱える値が桁あふれしていることが原因です。 longといえども(2の31乗-1)以上の値を扱うことは出来ません。 (負数を除いたunsined longだと2の32乗-1まで扱えます。) 負数になるのは符号ビットである 先頭のbitが1に反転してしまうので 表示上では負数と認識してしまいます(不正なデータ) 完全に桁あふれして0になったあとは 0に何をかけても0が続きます。

関連するQ&A

  • C言語の質問です。

    #include"stdio.h" int main(void){ int a, b, add; scanf_s("%d%d", &a, &b); add = a+b; printf("add=%d\n", add); return 0; } と、------------------------------------------------------------------------------ #include"stdio.h" int tasizan(int x, int y); int main(void){ int a, b, add; scanf_s("%d%d", &a, &b); add = tasizan(a, b); printf("add=%d\n", add); return 0; } int tasizan(int x, int y){ int aa; aa = x + y; return aa; } の違いを教えてください。

  • c言語なのですが

    c言語なのですが #include<stdio.h> main() { int a; printf("整数を5回足し算する\n"); scanf("%d %d",&a); printf("a*5=%d\n",a*5); return(0); } でエラーが起こります どこを修正すればいいのでしょうか

  • c言語についての質問です。

    #include<stdio.h> int main(void){ int a; printf("1文字たいぷしてください。\n"); scanf("%d",&a); if(a>=65 && a<=90){ printf("大文字です。\n"); } else if(a>=97 && a<=122){ printf("小文字です。\n"); } else{ printf("大文字でも小文字でもありません\n"); } return 0; } このプログラムは正しくなくて、 intをchar %dを%cにかえなければなりません。 なぜintはダメなんでしょうか? できれば丁寧に教えてください。 お願いします。

  • C言語でscanf()が先に実行されるのはなぜですか?

    C言語でscanf()が先に実行されるのはなぜですか? #include <stdio.h> int main(void){ int intNum; printf("整数を入力してください:\n"); scanf("%d", &intNum); printf("入力値は:%d\n",intNum); return(0); }

  • C言語の初心者です。これを実行してみてください。

    「a」って打ち込んだら「a」ってでましたか? #include<stdio.h> int main(void){ char a; printf("aaa\n"); scanf_s("%c", &a); printf("%c", a); return 0; }

  • C言語について

    次のような問題です。 問 自然数nを入力し、nを3で割って割り切れるかどうかを判定し結果を表示する。「割り切れる」、「1余る」、「「2余る」のいずれかが入るものとする。 このようなものをつくりました。 #include<stdio.h> int main(void) { int n; printf("自然数:"); scanf("%d",&n); if(n==0){ printf("割り切れる\n"); }else if(n==1){ printf("1余る\n"); }else{ printf("2余る"); } return(0); } これで合っているかよろしくお願いします。

  • C言語の配列について

    配列を20 定義し値を入力して合計値を出したいのですがどうすればよいのでしょうか 下のソースでエラーはおこりませんでした 何がちがうのでしょうか #include <stdio.h> int main() { int a[20]={}; int i, sum; printf("整数を入力してください:"); scanf("%d",&a); printf("\n"); for (i = 0; i < 10; i++) { sum += a[i]; } printf("sum= %d\n", sum); return 0; }

  • C言語の参照はずしについて

    ソートのプログラムなんですが #include <stdio.h> #include <stdlib.h> int comp(const void *, const void *); int main() { int i; int test[6] = {10, 8, 2, 6, 4, 0}; qsort(test, (size_t)6, sizeof(int), comp); printf("\n"); for (i = 0; i < 6; i++) printf("%d\n", test[i]); return 0; } int comp(const void *a, const void *b) { static int i = 1; printf("%02d--%d,%d\n", i, *(int *)a, *(int *)b); i++; return (*(int *)a - *(int *)b); } 最後のreturnの()の中身がよくわかりません。「参照はずし」という事をしてるらしいんですが「参照はずし」とは何ですか意味も教えてください。

  • C言語で困っています

    C言語で 100:1 99:2 98:3 .......ループ 1:100とやりたいんですが このやりかたがわかりません goto文などを使うのでしょうか? 一応コードは #include <stdio.h> int main(void) { int i,a; for(i=100; i>=1; i--){ for(a=1; a<=100; a++){ printf("%d:\n",i); break; printf("%d",a); } } return 0; } です まったくこれだと右側が出力されなくてだめみたいです どなたかお知恵をください お願いします

  • C言語

    このプログラムを作りたいのですが… ??????????? 物の総数を入れてください:12 取り出す物の数を入れてください:2 12個の異なる物から2個をを取り出す組み合わせの数は66です ?????????????? ここに出てくる数字は scanfで入れます。 だいたい こんな感じだと思うのですが… ***********の部分が わかりません。 ??????????????? #include<stdio.h> int factorial(int m,int r) { ************** } int main(void) {int a,b; printf("物の総数を入れてください:") scanf("%d",&a); printf("取り出す物の数を入れてください:") scanf("%d",&b); printf("12個の異なる物から2個を取り出す組み合わせの数は%dです。\n",a,b,factorial(a,b));) ?????????????? お願いします(>_<)