scanf関数に%d出力変換指定子を用いてint型の変数に数値を入力、printf出力表示したときにたまにでてくるモンスター数値-1073741824を2進数で表してみる

ぺろ、ぺろ、


ソーラー「わわ、かわいいなあ」


くきゅるるる 


ソーラーの左腕に巻きついて のんびり休むのが


おきにいりになったようで居心地がよさそうです。


移動するのも らくちんなようです。


こうしてscanf関数と


ソーラーはお友達になり一緒に暮らすこととなったのでした。


◇  ◇  ◇  ◇  ◇  ◇  ◇  ◇  ◇  ◇  ◇  ◇


ソーラー「さあ 元気よくおたべ~😊


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void){


int a;


printf("何か数値を入力してください。\n");


scanf ("%d",&a);


printf("入力した数値は%dです。\n",a);


return 0;


}

コンパイル結果

何か数値を入力してください。

野林檎(と入力すると)

入力した数値は4198575です。


scanf関数「うみゃい うみゃ~いぃ」



太陽の煌めく季節の中


お散歩、餌となる数値を拾い集めたり、


scanf関数に漢字をたべさせて4198575をprintf出力表示させたり、


また

お散歩して


ひらがなをたべさせて4198575をprintf出力表示させたり


低木の生い茂る綺麗な沼地であそんで


また英字をたべさせて4198575をprintf出力表示させたり


の楽しい日々となったのです。


scanf関数「むにゃはは


           -1073741824

                       」


ソーラー「?なんか 珍しい数値が出てきた?」


ソーラー 

「この-1073741824は2進数ではいくらなんだろうか。


-1073741824と対になる符号が反対で絶対値の大きさが同じ


正の数1073741824は


2進数では1000000000000000000000000000000とあらわされるけど・・・


そうか、


そういえば


2進数1000000000000000000000000000000の2の補数が


-1073741824の2進数表示となるよね。


(ある2進数の2の補数とは


ある2進数の0と1を入れ替えた2進数に1を足したものとなっています


詳しくは天国にいけるC言語入門 シーズン1


2の補数のエピソードをご覧ください)



よ~し1000000000000000000000000000000の2の補数をとって


-1073741824の2進数表示がいくらになるか確かめて見よっと。」


新種の蛇scanf

「くきゅるるっくきゅるるっ」


じたばたする。


ソーラー 「わっ、よろこんでる、よろこんでる。


それでは! スタンバイ!


1000000000000000000000000000000


の2の補数をもとめてみます。


アレサ「お待ちくださいですの。


1000000000000000000000000000000(31ビット)は


この場合 int(4バイト、32ビット)の型


に格納されています。


つまり


01000000000000000000000000000000(32ビット)と


メモリに格納されています。


ですので


int(4バイト、32ビット)の型に格納されている


2進数01000000000000000000000000000000


すなわち


1073741824



大きさが同じで符号がマイナスの


1073741824と対になる


-1073741824の


int(4バイト、32ビット)の型に格納されている


2進数を求めるには


この01000000000000000000000000000000の2の補数をとらなければ


いけないのではないですか?」


ソーラー「そういえば、そうだった


おなじビット同士の2の補数ができあがるんだった😊。


だから31ビットの2進数の補数ではなくて


32ビットの2進数の補数をとらなくちゃいけなかったんだよね。


では

01000000000000000000000000000000(32ビット)の2の補数をとろとろっと


01000000000000000000000000000000


の0と1の部分をひっくり返して


10111111111111111111111111111111


としたものに1を加えると


11000000000000000000000000000000


となる


つまりモンスター数値 -1073741824は


int(4バイト、32ビット)の型に


11000000000000000000000000000000と


格納されているわけなんだね。」


新種の蛇 「くるるるるる」


ソーラー「2の補数計算では 元の数とその2の補数は


同じ桁数におさめられるように計算される。


だから


01000000000000000000000000000000(32ビット)でなく


1000000000000000000000000000000(31ビット)の2の補数をもとめたらいけないんだね


試しに


1000000000000000000000000000000(31ビット)の2の補数をもとめ


てみます。


まずは


0と1をひっくり返して


0111111111111111111111111111111


これに


1を足すと


1000000000000000000000000000000(31ビット)になります。


このように


1073741824の値を表す


1000000000000000000000000000000(31ビット)


の2の補数は


-1073741824の値を表す?


1000000000000000000000000000000(31ビット)


であらわされ



(ここで面白いことがおこっています。


どこがおかしいか?


お気づきになられましたか?


つづきは次のエピソードをみてね。


                 solarplexussより)



1073741824の値を表す


01000000000000000000000000000000(32ビット)


の2の補数は


-1073741824の値を表す


11000000000000000000000000000000(32ビット)


であらわされます


31ビットに格納されていても

32ビットに格納されていても 


1000000000000000000000000000000(31ビット)


11000000000000000000000000000000(32ビット)


同じ

-1073741824を表しています


ビットが違えば


2の補数の数値表現がかわるので


注意、注意」


新種の蛇 「くるるるるる、きゅ、きゅい~~」


ソーラー 「はい、はい、ごはん」


_


_にごはんっと打ち込む


新種の蛇 「みゅ~んまい、むしゃむしゃ」


ソーラー

4198575

4198575

4198575

4198575

-1073741824


あれっ?


scanf関数のプログラムで


何かの条件がそろったとき


データを入力すると


-1073741824が出力されるね???


これがまた


-がついているのが


とってもナウいモンスター数値さんなんです。


・・・


  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます