質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

5回答

9959閲覧

2の補数の考えを用いてusigned intとintの格納できる値について考える

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/09/21 15:28

c言語、「2の補数(表現)とは何かを調べよ。それを用いて、unsigned int変数の格納できる値の範囲とint変数の格納できる値の範囲の違いについて説明せよ。」
という問題についてです。

自分で2の補数の計算について調べてみて「元の二進数について、各ビットを反転する(1を0に、0を1に)、最終ビットに(10進の)1を加算する」という方法までは理解しました。
また参考書を見てintは記憶できる値の範囲が「-21474836482147483647」,unsigned intは「04294967295」であるところまで把握しています。

しかし、2の補数の計算とunsigned int,intの関係性がよくわかりません。
この二つにどのような関係があるのでしょうか…
色々調べてみましたが説明にこぎつけません。

初学者ですが、ご教授頂けますでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

C言語自体には、intは少なくとも-32767~32767を、unsigned intは少なくとも0~65535を表現できること、という決まりがあるだけで、(unsigned) intの表現できる値の範囲も、負の数をどうやって扱うかも規格では決められていないことは心の片隅に留めておきましょう。負数が2の補数でない処理系は現実として皆無かも知れませんが、(unsigned) intが16bit幅な処理系にはまだまだ出会うチャンスがあるかも知れません。

で。以下intが16bitの場合を例にとります(ビットパターンを書く手間がましなので)が、

unsigned intは与えられたビットパターンを単純に数値におけばいいですから、intが16bitなら0~65535を表現できる、これは問題ないでしょう。

signed intで負数の表現に2の補数を使う場合は...
0と、1(0b0000000000000001)~32767(0b0111111111111111)とそれに対応する-1(0b1111111111111111)~-32767(0b1000000000000001)までは問題ないでしょう。
ここまでで使っていないビットパターンは0b1000000000000000です。これをビット反転して1を足すと0b1000000000000000自身に戻ってしまいます。これの符号を反転した値は、与えられたビット数では表現できないということ。ここで、この値に1を足すと0b1000000000000001つまり-32767なので、0b1000000000000000は-32768と解釈することができます。32768は表現できません。
以上より、16bit幅のsigned intは-32768~32767を表現できる、ということになります。

ビット数に対して一般化するなら、
(unsigned) intがN bit幅の場合、
unsigned intは0 ~ 2のN乗-1 を表現できる
2の補数表現を用いるsigned intは-(2の(N-1)乗) ~ 2の(N-1)乗-1 を表現できる
ということですね。

投稿2020/09/22 00:33

thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/09/22 00:47

規格上は、負の数の表現は「2の補数」「1の補数」「符号+絶対値」のどれかである、とのことです。 なお、C99で追加されたint8_t、int16_tなどの型は(存在すれば)2の補数であることが保証されています。
退会済みユーザー

退会済みユーザー

2020/09/28 12:51

詳細にありがとうございます。コメントにも感謝しております。
guest

0

ベストアンサー

質問のタイトル「2の補数の考えを用いてusigned intとintの格納できる値」で検索してみました。
分かりやすかったのでご参考までに。

4. データの表現法と変数
4-1-2. 2の補数表示(正負の整数を表現する 符号付整数)
イメージ説明

ビットパターンを0以上の整数と見ても、2の補数表示の整数と見ても足し算の電子回路は同じものが使えます。

すばらしい工夫です。

注意すべきは

1) 同じビットパターンでも符号付きか符号なしかで違う値に対応する事。
※1バイトのビット列11111111は符号付きでは値-1、符号なしでは値255を表す。

2) 符号無整数や2の補数表示は、C言語の整数値の記録方法として使われることが多い。
このため、C言語の整数は+1を続けると値が有限の範囲で循環する。(C言語の処理系依存)

投稿2020/09/21 23:20

mjk

総合スコア303

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/09/28 12:50

ありがとうございます。大変参考になりました。
guest

0

ビットパターン、を考えるとわかりやすいかと。
4バイトのintであれば、その数値の取りえる範囲は、
16進数表現では0x00000000 から0xffffffff となります
これをunsigned ではそのまま、0から4294967295を表現し、
signed では、0x00000000 から 0x7fffffffをプラスの数値とし、
0x80000000 から0xffffffff をマイナスの数値と表現します

投稿2020/09/21 15:44

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

2の補数の計算

という方向に行ってしまったのが間違いの元です。
それは、2の補数表現で、符号を反転させる(-1を掛ける)方法ですので、2の補数表現の理解が前提になります。

「2の補数表現」について考えましょう。

符号有り整数、符号無し整数との関係は、
MSBが1である数値、例えばオール1について、4294967295のような大きな整数と解釈するのが「符号無し整数」、2の補数表現とみなして-1のような負の数と解釈するのが「符号有り整数」です。

投稿2020/09/21 15:37

編集2020/09/21 23:15
otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/09/28 12:51

ありがとうございます。おかげさまで理解に近づきました。
guest

0

intの負の値には、2の補数を使ってデータが記録されています。
unsigned intは、それが無く、全てを正のデータとして処理します。

32bitとかあるintだと、想像がしにくいので、4bitの架空のmicro intという型を考えてみて、
micro int と unsigned micro int で、全てのビットパターンと、その値を表にしてみると、
何かが見えてくるかもしれません。

投稿2020/09/21 15:36

編集2020/09/21 15:39
amiya

総合スコア1218

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問