• ベストアンサー

このプログラム例が何を伝えようとしているのか分かりません(C言語)

下記のプログラムは『独習C 第3版』に記載されている、あるソースコードです。 #include <stdio.h> int main(void) { short i; i = 1; i = i | 32768; printf("%hd", i); return 0; } 【質問】 このプログラムの説明として、 『次のプログラムは、最上位ビットをセットすることにより、iを負数にします(ここでは、短整数が16ビットであると仮定しています)。』 とありますが、実際に実行してみると、 -32767 となり、iが負数の-1になっていません。 自分で 1000 0000 0000 0000 (32768) 0000 0000 0000 0001 (i) --------------------------- 1000 0000 0000 0001 OR として計算して、答えをWindows付属の電卓で確認したら「32769」になります。 このプログラムは何を伝えようとしているのでしょうか? どうして「-1」ではなく「-32767」のような結果になるのでしょうか? どなたか教えて頂けないでしょうか?

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「負数」というか, 「負の数」ですね. -32767 になる理由は, 「2の補数」を調べればわかるかも.

Guchiken
質問者

お礼

さっそくの回答ありがとうございます! 「i=1」でiにマイナス記号をつけて-1で負数だと思ってました。 あと、ちょっと調べるのが足らなかったようです…ごめんなさい! 自分で調べたところ、負数の表現には、符号付き絶対値、1の補数、2の補数があって、 そのうち2の補数表現が最も広く使用されており、2の補数は1の補数に1を加えたもの、ということが分かりました。 「-32767」はその2の補数表現で得られた数で、 0111 1111 1111 1111 (32767) これを1の補数にする(ビットを反転)。 1000 0000 0000 0000 これに1を加算。 1000 0000 0000 0001 (-32767) これが出力されていたことがわかりました。 回答ありがとうございました。

その他の回答 (3)

  • dsuekichi
  • ベストアンサー率64% (171/265)
回答No.4

ANo3です。 訂正。 > つまり、「Windows付属の電卓」は、今回の確認には使えません。 と書きましたが、つかいかたによっては・・・ > 答えをWindows付属の電卓で確認したら「32769」になります。 これは、先ほど書いた理由できませんが、逆、つまり、 「-32767を2進にするとどうなるか」 はできますね。 手順; (1)電卓を起動して関数電卓にする。 (2)「2進」を選択する (3)「Word」を選択する (4)「10進」を選択する (5)「32767」と入力して「+/-」ボタンを押す (6)「2進」を選択する これで、「1000000000000001」が求まります。

Guchiken
質問者

お礼

回答ありがとうございます。 手順どおり実際にやってみました。 今後、参考にさせていただきます!! 2度も回答本当にありがとうございました。

  • dsuekichi
  • ベストアンサー率64% (171/265)
回答No.3

> 次のプログラムは、最上位ビットをセットすることにより、iを負数にします > 何を伝えようとしているのか 単に「最上位BITをいじると、負数(符号が「-」)に変わる」と言う事で、 「符号付整数の最上位BITが符号管理に関っている」事を意識させたいだけでしょう。 #「-1を掛けた値になる」という意味ではないです。 > 答えをWindows付属の電卓で確認したら「32769」になります。 「Windows付属の電卓」のヘルプには、 > 16 進数、8 進数、または 2 進数を 10 進数に変換すると、正の整数になります。 とあります。 つまり、「Windows付属の電卓」は、今回の確認には使えません。

Guchiken
質問者

お礼

回答ありがとうございます!! 負数の表現にはいろいろあって、だから必ずしも最上位ビットが「1」になったからといって、その数にマイナス記号が付くわけではないんですね! 単に「符号がマイナスに変わる」というだけのものなんですね! Windows付属の電卓のヘルプを確認しました!ヘルプも役に立つときがあるんですね! 回答どうもありがとうございました。

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.2

>『次のプログラムは、最上位ビットをセットすることにより、iを負数にします(ここでは、短整数が16ビットであると仮定しています)。』 ここでの「iを負数にします」とは「iを、-32767と言う値の、負数にします」と言う意味です。 決して「iを-1にします」という意味ではありません。 >となり、iが負数の-1になっていません。 「-1になる」とは、どこにも書いてません。誰もそんな事は言ってません。 「負数になるとは、-1になる事である」って誰が決めたんですか?それは質問者さんの「勝手な思い込み」ですよ。 「-32767は負数」ですよ。「iが-32767になる」ってのは「iが負数になる」って意味も含んでます。 >1000 0000 0000 0000 (32768) >0000 0000 0000 0001 (i) >--------------------------- >1000 0000 0000 0001 OR ORした結果、最上位ビットが1になってますね。 0000 0000 0000 0000=0 0000 0000 0000 0001=1 0000 0000 0000 0010=2     | 0111 1111 1111 1110=32766 0111 1111 1111 1111=32767 1000 0000 0000 0000=-32768 1000 0000 0000 0001=-32767  ←ここに注目 1000 0000 0000 0010=-32766     | 1111 1111 1111 1110=-2 1111 1111 1111 1111=-1 >どうして「-1」ではなく「-32767」のような結果になるのでしょうか? 質問者さんが2進数でORした結果が「-32767と同じビット並び」になってますが、何か疑問でも?

Guchiken
質問者

お礼

回答ありがとうございます!! 「i=1」でiにマイナス記号をつけて-1で負数だと思ってました。 あと、ちょっと調べるのが足らなかったようです…ごめんなさい! 自分で 1000 0000 0000 0000 (32768) 0000 0000 0000 0001 (i) --------------------------- 1000 0000 0000 0001 OR と計算した答えが、負数の表現の1つである、「符号付き絶対値」の表現だと思い込んで、 最上位ビットの「1」が負を表し、残りのビット「000 0000 0000 0001」で絶対値1を表し、それで、「-1」だと思い込んでいました… 2の補数での表現であるとは思ってもいませんでした! それなら、「1000 0000 0000 0001」が「-32767」になるのも分かります。 お騒がせいたしました… 未熟者の私でも丁寧に回答していただき本当にありがとうございました。

関連するQ&A

  • C言語プログラム

    2つの整数を入力させ、それらが等しい場合hitoshii、異なる場合にはhitoshikunaiと出力するプログラムを作りたいのですが、うまくいきません。間違っているところを教えてください。 #include<stdio.h> #include<conio.h> void main() { printf("整数を入力してください:"); int number1; scanf("%d",number1); printf("整数を入力してください:"); int number2; scanf("%d",number2); if(number1==number2) { printf("hitoshii"); } else { printf("hitoshikunai"); } getch(); }

  •  現在、私はC言語を学んでいます。

     現在、私はC言語を学んでいます。  プログラミングの初期の初期の問題なんですが、 「Hello World」という有名なプログラムがありますよね? それについての質問です。 #include<stdio.h> main() { printf("Hello World"); return 0; } も #include<stdio.h> main(void) { printf("Hello World"); return 0; } も #include<stdio.h> int main() { printf("Hello World"); } もちゃんと表示できます。 ここで質問です。 int main(void) int main() main() main(void) はどう違うんですか? あと、 return 0; はあっても無くてもいいようなんですが どういう意味があるんでしょうか?

  • C言語の問題で困っています。

    C言語の問題で困っています。 誰か教えてください。 下の問題ですが、intがiだけでプログラムするにはどうしたら良いでしょうか? (a)から(d)に入るプログラムをすいませんが教えてください。 お願いします。 【問題】 1以上10以下の整数を昇順に区切って表示するプログラムです。 実行例 1 2 3 4 5 #include <stdio.h> int main (void) { int i; (A) while ((b)){ (c); (d); } printf("¥n"); return(0); }

  • C言語のプログラムについてです。

    円を描くプログラムを作りたいのですが、条件としてpointを使わないでつくらなければなりません。あとそのプログラムについての説明もいるので、合わせて回答お願いします。pointを使うと↓のプログラムです。 #include<stdio.h> #include<math.h> int main(void); int main(void) { double point[2][2]; double r; double pi=3.14159; int i; onenpl(); space(-100.0,-100.0,100.0,100.0); printf("円を描きます\n"); printf("半径を入力してください\n"); scanf("%lf",&r); point[0][0]=r*cos(0.0); point[0][1]=r*sin(0.0); for (i=1;i<360;i=i+1) { point[1][0]=r*cos(pi/180.0*i); point[1][1]=r*sin(pi/180.0*i); line(point[0][0],point[0][1],point[1][0],point[1][1]); point[0][0]=point[1][0]; point[0][1]=point[1][1]; } closepl(); return(0); }

  • C言語のコードについて

    C言語の問題なのですか、作成したのですが内容がわからないです。 コードをわかりやすく解説していただけると嬉しいです。 #include <stdio.h> void printBinary(unsigned char num) { int i ; /*①上位ビットから順に表示する*/ for(i = 7 ; i >= 0; i--) { /*②シフトとマスクを使用しています。*/ printf("%d", (num>>i) &0x01 ); } printf("\n"); } int main(void) { unsigned char num1 = 0xD2;/*11010010*/ unsigned char num2 = 0x5E;/*01011110*/ printf("0xD2 : "); printBinary(num1); printf("0x5E : "); printBinary(num2); return 0; }

  • while文について、c言語です。

    ぼくはプログラム始めたばかりです。ミスを見つけられた方、ご指導お願いします。 正整数nを入力して、nの階乗をもとめるプログラムを作りたいのですが、実行結果がいつも1になります。どこがおかしいか教えてください。以下のプログラムです。 #include <stdio.h> int main(void) { int i, n, s; printf("n = ?"); scanf("%lf", &n); s = 1; i = 1; while(i <= n) { s = s * i; i = i + 1; } printf("s = %3d\n", s); return 0; }

  • C言語について

    「条件演算子(a?b:c)を使って、三つの整数値を読み込んで、その最小値を求めて表示するプログラムを作成せよ」という問題を初心者なりに自分で以下のように解いてみたのですが、もっと簡単に表示できるプログラムがあれば教えてください。 #include<stdio.h> int main(void) { int na,nb,nc,min; printf("整数1:"); scanf("%d",&na); printf("整数2:"); scanf("%d",&nb); printf("整数3:"); scanf("%d",&nc); (na<nb)?min=na:min=nb; printf("最小値は%dです。\n",(nc<min)?min=nc:min); return 0; }

  • C言語初心者です。

    C言語初心者です。 1^2-2^2+3^3-4^2…+99^2-100^2の値を求めるプログラムを作成したいのですが上手くいきません。 どこが足りないのですか? #include <stdio.h> int main(void) { printf("%d", 1^2 - 2^2 + 3^2 - 4^2 … + 99^2 - 100^2); return (0); } よろしくお願いします。

  • C言語の、階乗を使うプログラムの問題を教えて下さい

    C言語の、このプログラムを作るのが分かる方、教えて下さい。階乗を使う問題です。 「キーボードで整数aを入力するとn!>aとなるときの最小のnを出力するプログラムを作りなさい」という問題です。 分からず苦戦しています。 nをキーボードで入力してn!を求めるには #include<stdio.h> int main(void) { int kekka,n,i; printf("n=? \n"); scanf("%d",&n); kekka=1; for(i=1;i<=n;i++) { kekka=kekka*i; } printf("%d!は%dです。\n",n,kekka); return 0; } とすればいいのは自分で作れたのですが、問題にあるn!>aのプログラムが分からず困っています。 分かる方、お願いいたします

  • c言語 プログラム ピラミッド

    プログラミングについて教えてください プログラムは ピラミッドの図形をユーザーが指定した数字で正三角形の ピラミッドの段数を指定できるプログラムです 例えば「5」と打てば ********* ■ ********■■■ ******■■■■■ ****■■■■■■■ **■■■■■■■■■ このような感じに表示されます *の部分は空白です #include<stdio.h> int main (void) { int num,i,j,h; printf("ピラミッドの高さを入力してください : "); scanf("%d" ,&num); for(i=1; i<=num; i++){ for(j=num; j>=i+1; j--){ printf(" ",j); } for(h=1; h<=j; h++){ printf("■"); } printf("\n"); } return 0; } ここまで出来ています、詰まっているのでご教授ください よろしくお願いします

専門家に質問してみよう