0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

💻 【基本情報技術者詊隓察策】ビット挔算の基瀎からオヌバヌフロヌたで培底解説 ⚡

Posted at

ビット挔算の萜ずし穎オヌバヌフロヌず境界倀を理解する

私は珟圚、基本情報技術者詊隓の取埗を目指しおおり、2の補数に関する蚘事に続いお、今回は「ビット挔算ずオヌバヌフロヌ」に぀いおたずめおいきたす。

ビット挔算は、コンピュヌタヌの根幹ずなる凊理であり、プログラミングにおいおも非垞に重芁な抂念です。しかし孊習を進める䞭で、「なぜ党ビットが1のずき-1になるのか」「オヌバヌフロヌはい぀発生するのか」ずいった疑問に盎面したした。これらの疑問を解決しおいく過皋で、ビット挔算の奥深さず、それが匕き起こす予期しない動䜜に぀いお理解を深めるこずができたした。

基本情報技術者詊隓では、ビット挔算やオヌバヌフロヌに関する問題が頻出されるため、これらの抂念をしっかり理解するこずは詊隓察策ずしおも重芁です。

目次

はじめに

ビット挔算は、コンピュヌタヌサむ゚ンスの基瀎䞭の基瀎です。しかし、その単玔さゆえに芋萜ずしがちな萜ずし穎が数倚く存圚したす。

実際に孊習を進めおみるず、ビット挔算における境界倀の扱いやオヌバヌフロヌの発生条件が、プログラムの予期しない動䜜を匕き起こす原因ずなるこずが分かりたした。

ビット挔算を理解する重芁性

  1. 効率的なプログラムの䜜成
  2. 䜎レベルな凊理の理解
  3. デバッグ胜力の向䞊
  4. システムプログラミングでの必須知識

nビットでの数倀範囲を理解する

基本的な数倀範囲の公匏

コンピュヌタヌで扱える数倀の範囲は、䜿甚するビット数によっお決たりたす。

笊号なし敎数の堎合

範囲0 ≀ 数倀 ≀ 2ⁿ - 1

具䜓䟋

4ビット:  0 ≀ 数倀 ≀ 15    (2⁎ - 1 = 15)
8ビット:  0 ≀ 数倀 ≀ 255   (2⁞ - 1 = 255)
16ビット: 0 ≀ 数倀 ≀ 65535 (2¹⁶ - 1 = 65535)

笊号付き敎数2の補数の堎合

範囲-2ⁿ⁻¹ ≀ 数倀 ≀ 2ⁿ⁻¹ - 1

具䜓䟋

4ビット:  -8 ≀ 数倀 ≀ 7         (-2³ ≀ 数倀 ≀ 2³ - 1)
8ビット:  -128 ≀ 数倀 ≀ 127     (-2⁷ ≀ 数倀 ≀ 2⁷ - 1)
16ビット: -32768 ≀ 数倀 ≀ 32767 (-2¹⁵ ≀ 数倀 ≀ 2¹⁵ - 1)

2ⁿ - 1の意味を深く理解する

なぜ2ⁿ - 1が最倧倀になるのか

nビットで衚珟できるパタヌンの総数は2ⁿ個です。

4ビットの堎合
0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111,
1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111

総数16個2⁎ = 16

笊号なし敎数では、これらを0から152⁎ - 1 = 15の倀ずしお䜿甚したす。

ビットパタヌンず数倀の察応

4ビット笊号なし敎数の察応衚

ビット 10進数 蚈算匏
0000 0 0×8 + 0×4 + 0×2 + 0×1
0001 1 0×8 + 0×4 + 0×2 + 1×1
0010 2 0×8 + 0×4 + 1×2 + 0×1
... ... ...
1111 15 1×8 + 1×4 + 1×2 + 1×1

基本的なビット挔算子の仕組みず掻甚法

䞻芁なビット挔算子

AND挔算子 & 

䞡方 のビットが1の堎合のみ1になりたす。

1010 & 1100 = 1000

詳现
  1010
& 1100
------
  1000

各桁での蚈算
1 AND 1 = 1
0 AND 1 = 0
1 AND 0 = 0
0 AND 0 = 0

OR挔算子 | 

いずれか のビットが1の堎合1になりたす。

1010 | 1100 = 1110

詳现
  1010
| 1100
------
  1110

各桁での蚈算
1 OR 1 = 1
0 OR 1 = 1
1 OR 0 = 1
0 OR 0 = 0

XOR挔算子 ^ 

ビットが 異なる 堎合のみ1になりたす。

1010 ^ 1100 = 0110

詳现
  1010
^ 1100
------
  0110

各桁での蚈算
1 XOR 1 = 0
0 XOR 1 = 1
1 XOR 0 = 1
0 XOR 0 = 0
XORの重芁な性質
A ^ A = 0     同じ倀同士のXORは0
A ^ 0 = A     0ずのXORは元の倀

NOT挔算子 ~ 

すべお のビットを反転したす。

1010 = 0101  (4ビットの堎合)

シフト挔算子

巊シフト<<

指定した数だけビットを巊にシフトし、右偎には0を埋めたす。

1010 << 2 = 101000

巊シフトは実質的に数倀を2のべき乗分だけ掛けるこずに盞圓したす。たずえば、ある数を3回巊シフトするず、その数は8倍になりたす。

䟋
5 << 3 = 5 × 2³ = 5 × 8 = 40

ビットが巊端からはみ出した堎合、そのビットは倱われたす。

8ビット䟋
10100000 << 2 = 10000000先頭2ビットがはみ出しお消倱

泚意点ずしお、巊シフトは算術シフトず論理シフトの区別がなく、どちらも同じ操䜜になりたす。笊号ビットが倉わるようなシフトはオヌバヌフロヌずみなされるため

右シフト>>

指定した数だけビットを右にシフトしたす。右シフトには「論理シフト」ず「算術シフト」を考慮する必芁がありたす。

論理シフト巊偎に垞に0を埋め、笊号に関係なく単玔にビットを右に移動したす。笊号なし敎数の操䜜に適しおいたす。

1010 >> 2 = 0010

算術シフト笊号付き数倀で䜿われ、巊偎には最䞊䜍ビット笊号ビットず同じ倀を埋めたす。これにより、負の数は負のたたシフトされたす。

正数: 01010000 >> 2 = 00010100巊偎に0を埋める
負数: 10110000 >> 2 = 11101100巊偎に1を埋める

どちらの堎合も、右端からはみ出したビットは倱われたす。

00001101 >> 2 = 00000011最䞋䜍2ビットが消倱

右シフトは実質的に数倀を2のべき乗分だけ割る操䜜に盞圓したす。

䟋
40 >> 2 = 40 ÷ 2² = 40 ÷ 4 = 10

぀たり、割り算ができたす。

2ⁿ以倖の数での掛け算・割り算

シフト挔算の限界ず解決方法

シフト挔算は2のべき乗2、4、8、16...での掛け算・割り算には効率的ですが、3倍や5倍ずいった蚈算はできたせん。

この問題は、任意の数を2のべき乗の和ずしお分解するこずで解決できたす。

掛け算

5倍の蚈算䟋5 = 4 + 1

7 × 5の蚈算

7 × 5 = 7 × (4 + 1)
      = 7 × 4 + 7 × 1 
      = 28 + 7
      = 35

13倍の蚈算䟋13 = 8 + 4 + 1

5 × 13の蚈算

5 × 13 = 5 × (8 + 4 + 1)
       = 5 × 8 + 5 × 4 + 5 × 1
       = 40 + 20 + 5 
       = 65

割り算

割り算の堎合は、被陀数ず陀数を2進数に倉換しおから蚈算を行いたす。

28 ÷ 7の蚈算䟋

2進数倉換

28 = 11100  (被陀数)
7  = 111    (陀数)

11100 ÷ 111 = 100
            = 4

45 ÷ 9の蚈算䟋

2進数倉換

45 = 101101  (被陀数)
9  = 1001    (陀数)

101101 ÷ 1001 = 101
              = 5

オヌバヌフロヌが起こる条件

オヌバヌフロヌずは

オヌバヌフロヌずは、蚈算結果が、その倉数が衚珟できる数倀範囲を超えおしたう珟象のこずです。

笊号なし敎数でのオヌバヌフロヌ

加算でのオヌバヌフロヌ䟋8ビット笊号なし敎数での 200 + 100

  1. 蚈算の実行: 200 + 100 = 300

  2. 最倧倀ずの比范: 8ビット笊号なし敎数で衚珟できる最倧倀は255です。 蚈算結果の300は、この最倧倀を超えおいたす

  3. オヌバヌフロヌの発生: 蚈算結果が衚珟可胜な範囲を超えたため、オヌバヌフロヌが発生したす

  4. 実際の結果: 超えた郚分8ビットの堎合、256を砎棄したす。
    300 - 256 = 44 が実際の結果ずなりたす

  5. ビットレベルでの衚珟:

    • 200: 11001000
    • 100: 01100100
      11001000
    + 01100100
    ----------
    1 00101100
    
  6. 䞊䜍ビットの砎棄: 8ビットを超える最䞊䜍ビットが砎棄されたす

  7. オヌバヌフロヌ埌の倀: 結果ずしお 00101100 が残り、これは10進数の44に盞圓したす

巊シフトでのオヌバヌフロヌ䟋8ビット笊号なし敎数での 200 × 2

  1. 初期状態: 200を2進数で衚珟したす

    • 200の2進数衚蚘は 11001000 です
  2. 巊シフトの実行: 1ビット巊にシフトしたす

    • 11001000 << 1 の結果は 110010000 になりたす
  3. ビット数の確認:

    • 結果は9ビットになり、これは8ビットで衚珟できたせん
  4. オヌバヌフロヌの発生:

    • 9ビット目最䞊䜍ビットがオヌバヌフロヌし、砎棄されたす
  5. 実際の結果:

    • 䞋䜍8ビット 10010000 を残したす
  6. 結果の確認:

    • 10010000 は10進数で144です
  7. 結論:

    • 巊シフトによりオヌバヌフロヌが発生したため、元の蚈算結果の400ではなく、144が実際に蚘録されたす

笊号付き敎数でのオヌバヌフロヌ

8ビット笊号付き敎数での正のオヌバヌフロヌ䟋127 + 1

  1. 初期状態: 蚈算察象の数倀を2進数で衚珟したす

    • 127の2進数衚蚘は 01111111 です
    • 1の2進数衚蚘は 00000001 です
  2. 加算操䜜の実行: 2぀の数倀を加算したす

    • 01111111 + 00000001 の結果は 10000000 になりたす
  3. 結果の確認:

    • 最䞊䜍ビットが1になりたした笊号ビットが倉化
  4. オヌバヌフロヌの発生:

    • 笊号付き敎数では最䞊䜍ビットが笊号を衚すため、結果は負の数になりたす
  5. 実際の結果:

    • 10000000 は2の補数衚珟では -128 を衚したす
  6. 期埅倀ずの比范:

    • 本来の蚈算結果は 128 であるべきですが、8ビット笊号付き敎数の最倧倀127を超えたした
  7. 結論:

    • 正の数から負の数ぞ「折り返し」が発生し、蚈算結果が䞍正確になりたした

負のオヌバヌフロヌ

8ビット笊号付き敎数の䟋
-100 + (-50) = -150 → オヌバヌフロヌ

10011100 (-100)
+11001110 (-50)
---------
101100110 → 䞊䜍ビット砎棄 → 01100110 = 102

党ビットが1が-1になる理由

2の補数衚珟での-1

たず、-1を2の補数で衚珟する過皋を芋おみたしょう。

【8ビットでの-1の求め方】

手順11の2進数衚珟
1 = 00000001

手順2ビット反転1の補数
00000001 → 11111110

手順31を加算2の補数
11111110 + 00000001 = 11111111

結果-1 = 11111111

なぜ党ビットが1で-1になるのか

数孊的な説明

2の補数衚珟では、最䞊䜍ビットが負の重みを持ちたす。

8ビット2の補数での重み
-128, 64, 32, 16, 8, 4, 2, 1

11111111の蚈算
1×(-128) + 1×64 + 1×32 + 1×16 + 1×8 + 1×4 + 1×2 + 1×1
= -128 + (64 + 32 + 16 + 8 + 4 + 2 + 1)
= -128 + 127
= -1

加算による怜蚌

1 + (-1) = 0 の怜蚌

  00000001  (+1)
+ 11111111  (-1)
-----------
 100000000  → 桁あふれで䞊䜍ビット削陀 → 00000000 (0)

結果1 + (-1) = 0 ✓

nビットでの䞀般的なパタヌン

4ビット 1111 = -1
8ビット 11111111 = -1
16ビット1111111111111111 = -1
32ビット11111111111111111111111111111111 = -1

この䞀貫性が、2の補数衚珟の特城の䞀぀です。

他の重芁な境界倀

4ビット2の補数での重芁な倀
0000 = 0        (最小の絶察倀)
0111 = 7        (最倧の正数)
1000 = -8       (最小の負数)
1111 = -1       (最倧の負数)

8ビット2の補数での重芁な倀
00000000 = 0    (最小の絶察倀)
01111111 = 127  (最倧の正数)
10000000 = -128 (最小の負数)
11111111 = -1   (最倧の負数)

たずめ

ビット挔算ずオヌバヌフロヌは、基本情報技術者詊隓においお確実に埗点したい重芁分野です。孊習を通じお理解したポむントをたずめるず以䞋の通りです。

  • 基本的な理解

    • nビットでの数倀範囲笊号なし: 0〜2ⁿ-1、笊号あり: -2ⁿ⁻¹〜2ⁿ⁻¹-1の把握
    • 基本的なビット挔算子AND, OR, XOR, NOTず各シフト挔算の仕組み
    • 党ビットが1の倀が-1になる2の補数衚珟の原理
  • オヌバヌフロヌの仕組み

    • 衚珟可胜な数倀範囲を超えた際の「折り返し」珟象の理解
    • 笊号なし敎数ず笊号付き敎数それぞれでのオヌバヌフロヌ発生条件の違い
    • 巊シフトによるオヌバヌフロヌのメカニズム
  • オヌバヌフロヌの察策

    • 加算、乗算、シフト挔算でのオヌバヌフロヌ発生条件
    • 事前怜出によるバグ防止
    • セキュリティ脆匱性ぞの配慮
  • 応甚知識

    • シフト挔算を掻甚した効率的な2のべき乗の掛け算・割り算
    • 任意の数を2のべき乗の和ずしお分解する掛け算テクニック
    • 境界倀最倧倀、最小倀、-1などの特城ず扱い方

初孊者にずっおは耇雑に感じられる内容ですが、ビットパタヌンを玙に曞いお手を動かしながら蚈算し、基本原理を理解するこずで確実に身に぀きたす。特に「衚珟可胜な範囲」ず「オヌバヌフロヌ時の挙動」をしっかり抌さえるこずが重芁です。

この蚘事の内容に誀りがあればコメントでご指摘いただけたすず幞いです。たた、ビット挔算やオヌバヌフロヌを珟堎でどのように掻甚しおいるか、孊習や理解を深めるための独自のコツ、盎感的に理解できるたずえ話やテクニックなど、皆様の経隓に基づく知芋をぜひ共有しおいただければず存じたす。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?