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

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

ただいまの
回答率

90.33%

  • 基本情報技術者

    49questions

    基本情報技術者とは、経済産業省が行う国家資格「情報処理技術者試験」の区分の一つです。試験ではプログラマーやシステムエンジニアなどIT業界で働くために必要とされる基礎知識や情報処理において論理的な考え方ができるか等が問われ、企業から高い評価を獲ることができ、IT業界の入門的な資格として人気があります。

【基本情報技術者】2の補数について

受付中

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 1,026

ai5

score 32

基本情報処理技術者

固定長の2進数の足し算を行うと、繰り上がって、桁が増えることがあります。
このような場合、固定長からあふれたビットは切り捨てます。

→なぜ切り捨てるかわからないです

参照元URL
https://ja.wikipedia.org/wiki/%E3%83%93%E3%83%83%E3%83%88%E6%BC%94%E7%AE%97

・2進数の足し算
7+7を下記のように2進数に変えて計算したとき

0111
+0111
────
1110→ 0011(+2)

なぜ1110が0011になるのでしょうか?

参照書籍
うかる!福嶋先生の集中ゼミ基本情報技術者 45P

お手数ですがご教授ください。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+4

切り捨てない場合、溢れたビットの居場所がないからです。

例えば 12 までしか数が無い場合、13 時は 1時になります。13 時なのか 1 時なのかは状況によって判断します。
この質問の場合も、桁溢れしたら桁溢れレジスタにフラグが立ちます。溢れたことが重要だとしたら、どこか別に自分で保存して使いますし、要らなければ捨て置きます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/13 17:17

    早速ご回答ありがとうございます。

    そのお考えがベースだとして
    なぜ1110が0011になるのでしょうか? 途中の経緯というかどういう流れで0011になったかが検討つかないです。

    キャンセル

  • 2017/03/13 17:42 編集

    7 + 7 = 14 で、2 進数で表すと 1110 になります。
    この数に 0010 すなわち 2 を足すと 0000 になります(10000 が桁溢れします)。
    つまり 1110 は 0 より 2 少ない数、-2 と見なすことができます。
    同じ数が 14 であったり -2 であったりするので、ルールを決めて、一番上のビットが 1 であったらマイナスと見なそうという扱い方があります。
    この時、一番上のビットを符合と呼びます。

    このあたりの流れがバッサリ省略されていますが、ちゃんと順番に読んでいきましたか?

    1110 は 0011 ではありません。相当の飛躍があると思いますので、飛ばさず読んで行きましょう。

    すみません。数を書き間違えて何度か書き直しました。

    キャンセル

  • 2017/03/13 17:54

    次へ行く前に https://teratail.com/questions/67719 を自分の物にしましょう。基礎を作らず建物を建ててもひっくり返ります。

    キャンセル

  • 2017/03/13 18:27 編集

    7 + 7 = 14 で、2 進数で表すと 1110 になります。
    この数に 0010 すなわち 2 を足すと 0000 になります(10000 が桁溢れします)。
    →これは1110をマイナスの符号表記にさせるために足したときに桁あふれする2を選んで足したのでしょうか?


    順々には読んでいて
    0111
    + 1100 <= -4
    ------
    10011 はわかります。

    ですが、参考書に書いてあるままの
    0111
    +0111
    ────
    1110 が→ 0011(+2) を読んだところ、なんでだろうという思いが拭えないです。

    キャンセル

  • 2017/03/13 20:30

    ここだけ読んでいるからわけがわからなくなるんだろうと思いますよ。もっと前から順に読んでいきましょう。1110 = 0011 にはなりません。読み違えています。矢印の意味はイコールではなく、別の何かです。

    キャンセル

  • 2017/03/13 20:41

    ちなみに、1110 の 2 の補数は 0010 です。これは 10 進数で言うと 2 になります。0011 は 10 進数で言うと 3 になります。この部分だけ読んでも、どういう流れで書かれているのか、その本を持っていないのでわかりません。

    キャンセル

  • 2017/03/14 09:39 編集

    すみません少し説明を省略していたようだったので、訂正追記します。

    もう少しでわかるかもしれません。
    ・2進数の足し算
    (1)
    0111   ⁺7
    + 1100   -4
    ------
    10011

    (2)
    0111
    +0111
    ────
    1110 が→ 0011(+2)負数になった2の補数を計算して整数に

    (2)は計算結果である1110が負数という意味ですか?
    5桁目が1だから負数という意味なんでしょうか?

    1110という答えが出たのになぜわざわざこのような計算をしているかわからないです。

    キャンセル

  • 2017/03/14 10:40

    この部分だけ読んでも、どういう流れで書かれているのか、その本を持っていないのでわからないと書きました。あなたが読み間違えているのか、本が間違えているのか、その本を持っていないのでわかりません。ですから、一般的な説明を書きました。

    説明を省略していたので追記するなら、説明を追記してください。質問を追記されてもこちらには何の情報も入ってきません。「<=」というのは何を意味する記号ですか? 0011(+2) とはどういう意味ですか? すぐ前に書いたように、0011 は +2 ではなく +3 です。そもそも、人の説明を読んでいますか?

    キャンセル

  • 2017/03/14 11:48 編集

    説明は読んでるのですが、本には0011(+2)という書き方になっていて私自身わからないです。すみません

    前置きには、固定長の2進数の足し算を行うと、繰り上がって、けたが増えることがあります。このような場合、固定長からあふれたビットは切り捨てます。

    例えば、7-4も、7+(-4)で計算することができます。4の2進数は0100で、2の補数はビットを反転した1011に1を加えた1100です。とかいてありました。

    キャンセル

  • 2017/03/14 12:00

    飛ばし読みをせずにもっと丁寧に読みましょう。前後の文章が全くつながっていないことにお気づきでないですか?

    キャンセル

  • 2017/03/14 12:01

    「固定長からあふれたビットは切り捨てます。例えば…」とあれば、固定長からあふれたビットを切り捨てる例がくるべきです。ところが全く違う文脈になっています。これでは読めません。本にはその間が書いてあったはずです。

    キャンセル

  • 2017/03/14 14:42

    ビット切り捨ての例はないです。
    この参考書いろいろ省略されてるかもしれません。。。

    なので、すべて書くとこのような流れです。

    2の補数を使う理由
    固定長の2進数の足し算を行うと、繰り上がって、けたが増えることがあります。このような場合、固定長からあふれたビットは切り捨てます。

    例えば、7-4も、7+(-4)で計算することができます。4の2進数は0100で、2の補数はビットを反転した1011に1を加えた1100です。

    ・2進数の足し算
    (1)
    0111   ⁺7
    + 1100   -4
    ------
    10011

    (2)
    0111
    +0111
    ────
    1110 → 0011(+2)

    負数を2の補数で表現しておくと、足し算だけで加減算を行うことが出来ます。
    コンピュータでは、減算を加算回路だけで行うことが出来る。
    負数を2の補数で表すとき、4ビットで表現できる値の範囲は、-8~+7でした。
    7+7の計算をすると、表現できる値の範囲を超え、負数のー2になってしまいます。

    キャンセル

  • 2017/03/14 15:18

    じゃあもうその本投げ捨てたほうがいいのでは

    キャンセル

  • 2017/03/14 15:44

    それが全文なら分かりにくいですね。別の本にした方がいいかも知れません。

    キャンセル

  • 2017/03/14 15:58

    > 1110 が→ 0011(+2)負数になった2の補数を計算して整数に
    「0011」は「0010」の誤植でしょう (質問者さんが正確に引用していればですが)。

    キャンセル

  • 2017/03/14 16:00

    これ、1110 → 0011 (+2) って、1110 という数値をさらに符号変換(2の補数)して、結果が2 である、すなわち元々の結果が -2 である、というのを示したいんじゃないでしょうか。でもって 0011 は……0010 の誤植、あるいは誤りではないかと。

    キャンセル

  • 2017/03/14 16:01

    この本の著者の Web ページがある(http://福嶋.jp/)ようなので、こちらを見て質問してみるのもいいかもしれません。

    キャンセル

  • 2017/03/14 16:09

    私も正誤表がないかと見てみましたが、この箇所にはなかったですね。

    キャンセル

  • 2017/03/14 16:31 編集

    2番の表記は少しわけがわからないですね・・・
    私も日本経済新聞出版社の正誤表見てみましたが、それらしいものはなかったです。

    キャンセル

  • 2017/03/14 16:48

    本のamazonレビューを見てみました。内容からして午前編と思い、2017年版のレビューはなかったので2016年版を見てみたのですが、なぜか「アルゴリズム」がどうこうというレビューが…

    キャンセル

+4

以下の回答は多くの部分に推測を含みます。正しい条件等は当該書籍を確認してください。

まず、この問題は4ビットの符号付整数での計算と考えられます。
符号付整数では最上位ビットが1である場合、負数の2の補数表現ととらえます。
これを踏まえて、まず2進数で7+7を計算します。これは

  0111 <=7
+ 0111 <=7
──── 
  1110


となりました。符号なしなら10進数の計算通り「14」と解釈されるところですが、これは符号付整数で、最上位が1になっているため、負数の2の補数表現で解釈しなければなりません。

1110の2の補数、つまりこれと和をとって桁上がりし5ビットになる最小値は

  10000 <=5ビット最小値
-  1110
────
   0010 =>2


2です。したがって、1110は-2と解釈されます(ここが本のミスか書き写し間違い?)。

正の整数同士の和をとって負数になるのは普通の世界ではありえないのですが、コンピュータの世界ではこのようなことが起こります。これは、「7+7」がこの符号付4ビット整数で表現できる最大値「7」を超えてしまうため起こる現象です。これをオーバーフローと呼びます。

2の補数

そもそも2の補数とかコンピュータの表す数の意味が分かっていないようなのでこの辺にも触れておきます。
まず基本的にコンピュータは加算は得意ですが減算は苦手です。
苦手な減算を得意な加算に置き換え、全体の整合性が取れるように、2の補数表現があるのです。

2だとなじみにくいでしょうから、いつも使っている10進数で考えましょう。
7325-1589を計算しようとすると、繰り下がりが多く一般の人が暗算しようとしても結構面倒です。
では、この引く数1589を、10000-xという形で表せたらどうなるでしょう?

7325-1589 = 7325-(10000-x)
          = 7325-10000+x
          = (7325+x)-10000


となります。減算の繰り下がりに比べたら加算の繰り上がりのほうが簡単で、
10000引くという計算は簡単なので、そのまま減算するより楽になります。
こういうxを、今は10進数で考えているので、10の補数表現といいます。
4桁で考えた場合、最後の10000引く操作は桁あふれした分を除外することに相当します。

このxを求めると、1589=10000-xですから、x=10000-1589となります。
やっぱり繰り下がりのある引き算になるじゃないか…となりそうですが、この計算を

x =  10000 -1589
  = (9999+1)-1589
  = (9999-1589)+1
  = 8410 +1
  =8411


とします。3行目のカッコ内は10進数で使う最大の数字9が並んだ数からの引き算なので、繰り下がりなく引き算ができます。このカッコの計算で出てきた8410は、1589の9の補数というものです。10の補数より1小さいので9の補数というわけです。

これと同じことを2進数でもやるわけです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

説明を写し間違えてはいませんか?

「2の補数について」という事なので、以下のような計算についての解説だったのではないでしょうか?

4ビット長の2進数で、負の数を2の補数で表現する時、7-4を計算する。

負の数を2の補数で表すので、7-4の計算は、7 + (-4)を求めれば良い。

手順1: -4 を2の補数で表す。
2の補数は、1の補数に1を加えたものだから、以下の計算で 1100 と求まる。

   1111
 - 0100   <= 4
 +    1
 ------
   1100

手順2: 7 + (-4) を計算する。

7を2進数で表すと 0111、 -4は1100だから

  0111
 + 1100  <= -4
 ------
  10011

ここで、5桁目に繰り上がった1を切り捨てると、 0011 (10進数で3)が得られて、
7-4=3の計算が出来た。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

もとの書籍に何がかいてあるのかよくわからないので、わかることだけ回答します (結局、他の方と同じことを説明しているのですが)。

 #1

まずは、わかりやすい10進法でやってみます。

最初に、例として次の筆算をやってみましょう。

   10000
-)  3602
---------


このようになります。

    ₉₉₉
   10000
-)  3602
---------
    6398

1の位では、0から2は引けないので上の桁から10を借りてきて、10 - 2 = 8です。10の位では、1借りたのでさらに上の桁から借りてきて9にして、9 - 0 = 9です。100の位、1000の位も同じです。

ここで興味深いのは、10の位から上では9から引けばよいが、1の位だけはひとつ多い10から引く、ということです。ですから、次のように計算しても結果は同じです。

    9999
-)  3602
+)     1
---------

このように、10000から引く場合は、あらかじめ1少ない9999から引いておいてあとで1を足せば、上の位から借りる必要もなくなります。

    9999
-)  3602
    ₆₃₉₇
+)     1
---------
    6398

計算途中の引き算の結果は、どの桁でも単に9から引いているだけです。各桁の結果は次のようになっています。

引く数 0 1 2 3 4 5 6 7 8 9
結果 9 8 7 6 5 4 3 2 1 0

このように、10進法のある数について、各桁の数を9から引いた数を、その数に対する9の補数と言います。上の引き算では、桁借りのような複雑なことをしなくても、10種類の補数を知っていれば引き算ができます。ただし、あとで1を足す必要はありますが。ある数の9の補数に1を足した数を、その数に対する10の補数と言います。

 #2

次に、10の補数を使えば一般の引き算もできることを示します。

例として次の筆算をやってみましょう。

    4325
-)  3602
---------


このようになります。

    ₃ ₁
    4325
-)  3602
---------
     713

1の位と100の位を計算するときに、上の桁から借りています。なんだか面倒です (面倒だと思わないかもしれませんが)。

ところで、この計算では4桁しか使いませんから、10000の桁に1を付け足して、あとでそれを削っても同じ結果になるはずです。

    4325
+) 10000
-)  3602
-) 10000
---------

10000 - 3602のところは、さっきやった方法で計算できます。

    4325
+)  9999
-)  3602
+)     1
-) 10000
---------

つまり、

    4325
+)  6398   ← 3602に対する10の補数
   ₁₀₇₂₃
-) 10000
---------
     723

補数計算によって、引き算が足し算に変わりました。よって、次のことが言えます。

  • ある数を引くには、その数の10の補数を足せばよい

またここでは、4桁以下の計算しかしません。計算の途中や結果に現れる数は10000未満です。よって、いちいち「前に1を付け足して、あとでそれを削って」と考えるまでもなく、次のように考えても結果は同じです。

  • 計算結果に必要な桁数以上の桁が現れたら、無視する。

 #3

上記のように、10の補数を使えば、引き算が足し算でできることがわかりました。では、次の引き算はどうなるでしょうか。

       0
-)  3602
---------

上の#1でやった計算方法を機械的にあてはめれば、この結果は3602に対する10の補数である6398になります。

また、#2で見たように、他の数に6398を足せば3602を引いたことになるのですから、この6398は-3602と同じものだと考えても差支えないでしょう。つまり、ある数に対する10の補数は、その数の符号を反転したものを表すと考えることができます。

       0
-)  3602
---------
    6398 = -3602

ただし、これが言えるためには、次のことに注意しなければなりません。

  1. 扱う数の最大桁数があらかじめ決まっていること。
  2. 結果が、表せる数の範囲を超えないこと。

このうち1.については、上の例で説明した通りです。4桁を超える数を扱わないと決めたから、それより上の桁に出てくる数字を無視しても計算が成り立つのです。

また2. についてですが、全てが符号なし数で表されるので、そのままでは結果が正の数なのか、10の補数で表される負の数なのか区別がつきません。4桁で表される数のうちどこからが負の数か、どこまでが正の数かを決めておく必要があります。

一番わかりやすいのは、「最上位桁が5以上なら負の数」と決めることでしょう。正の数の範囲と負の数の範囲とをほぼ均等に表せます。実際は負の数の範囲のほうが1つ広くなります。4桁だと、正の数の範囲は1~4999なのに対し、負の数の範囲は5000~9999 (-5000~-1) となります。

なお、ここでは説明しませんが、算術オーバフロー (決まった桁数で表せる数の範囲を計算結果が超えてしまう) を検出するためには、範囲の定義を上のようにすると便利です。

 #4

以上では10進法を使って説明しましたが、2進法にあてはめれば、問題を理解できると思います。

ヒント: 10進法の9の補数、10の補数に対し、2進法では1の補数2の補数を使います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/14 16:05 編集

    ご質問に挙げられた書籍の最初のほうの説明だけ読みましたが、「基本情報処理には薄い参考書を終わらせてすぐ問題演習にとりかかるという必勝法がある」「6割取れれば合格なので、本書では試験範囲全部を網羅していない」(いずれも大意) とかいったことが書いてありました。ここで本を閉じたので、中身は見ていません。

    中を見ていないので想像ですが、「ヤマを丸暗記して得点を稼げばいい」というタイプの参考書のように思いました。そういうもので要領よく合格する人もいるのかもしれません。しかし、質問者さんのように「なぜこうなるのかわからない」という疑問を放っておけない人には、向かない参考書なのではないでしょうか。

    また、丸暗記主義だとすれば、本サイトのような場所で質問し理解しながら学習していくのにも向かないということになると思います。

    キャンセル

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

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • 基本情報技術者

    49questions

    基本情報技術者とは、経済産業省が行う国家資格「情報処理技術者試験」の区分の一つです。試験ではプログラマーやシステムエンジニアなどIT業界で働くために必要とされる基礎知識や情報処理において論理的な考え方ができるか等が問われ、企業から高い評価を獲ることができ、IT業界の入門的な資格として人気があります。