開発

2の補数とは|負の数の表し方・反転して+1する理由・ビット幅と範囲を解説

コンピュータはマイナス記号を持たず、0と1のビットだけで負の数を表します。その主役が「2の補数」です。本記事では、2の補数とは何か、なぜビットを反転して1を足すのか、符号ビットの役割、オーバーフロー、そして8・16・32ビットで表せる数の範囲までをやさしく解説します。

公開: 2026-10-16

プログラムで整数を扱っていると、マイナスの値が思わぬ大きな数になったり、計算がぐるりと一周して符号が反転したりする場面に出会うことがあります。その背後にあるのが2の補数(にのほすう、two's complement)という、コンピュータが負の数を表すための仕組みです。コンピュータはマイナス記号「-」を持たず、0と1だけで負の数を表現しなければなりません。本記事では、2の補数とは何か、なぜビットを反転して1を足すのか、そしてビット幅によって表せる数の範囲がどう決まるのかを、順を追って解説します。

2の補数とは何か

2の補数とは、コンピュータの内部で負の整数を表現するための方式です。私たちが普段使う数では、数の前に「-」を付けて負の数を表しますが、コンピュータが扱えるのは0と1のビットの並びだけです。そこで、一定のビット幅の中で「ある数を足すと桁あふれして0に戻る相手」を、その数の負の値とみなす、という発想が使われます。

たとえば8ビットの世界では、表せる値は0から255までの256通りです。この256通りを「ぐるりとひとつの輪」として考え、輪の後半(128以上)を負の数の領域に割り当てるのが2の補数のアイデアです。具体的には、ビット列の先頭ビット(最上位ビット)が1なら負、0なら0以上の数、というルールで読み替えます。

この方式の最大の利点は、足し算の回路をそのまま引き算にも使えることです。負の数を特別扱いせず、足し算と同じハードウェアで計算できるため、現代のほぼすべてのコンピュータが整数の表現に2の補数を採用しています。ビットの並びがどんな数として読めるのかは、基数変換ツールで2進数と10進数を行き来しながら確かめると、感覚をつかみやすいでしょう。

なぜ負の数を補数で表すのか

負の数の表し方には、2の補数のほかにもいくつか案があります。代表的なのは、先頭ビットを単なる符号として使う符号付き絶対値と、すべてのビットを反転させる1の補数です。しかし、これらには扱いにくい弱点があります。

  • 符号付き絶対値:「+0」と「-0」という2種類のゼロが生まれてしまい、また足し算のときに符号を見て処理を分岐する必要があります。
  • 1の補数:こちらも+0と-0の2つのゼロが存在し、桁あふれ(キャリー)を末尾に足し戻す特別な処理が必要になります。

これに対して2の補数では、ゼロの表現がただ一つに定まり、+0と-0の区別が生まれません。さらに重要なのは、正の数も負の数も区別せず、まったく同じ足し算の手順で計算できる点です。たとえば「5 + (-3)」を計算するとき、-3を2の補数で表した値を5に足すだけで、自然に2という正しい答えが得られます。引き算を「負の数の足し算」に置き換えられるため、ハードウェアを単純にできるのです。

つまり2の補数は、ゼロが一つに定まり、足し算回路を共有できるという、設計上の合理性によって選ばれている方式だと言えます。

2の補数の作り方:反転して1を足す

ある数の2の補数(=符号を反転させた値)を求める手順は、とてもシンプルです。すべてのビットを反転(0と1を入れ替え)して、その結果に1を足す。これだけです。8ビットで「3」の符号を反転させて「-3」を作ってみましょう。

3 = 0000 0011
ビット反転 → 1111 1100
1を足す → 1111 1101 = -3

逆に、この「1111 1101」を再び反転して1を足すと、元の「0000 0011 = 3」に戻ります。同じ操作をもう一度行うと元に戻るのが2の補数の性質で、これは「-(-3) = 3」という数学的な関係とぴたりと一致します。

なぜ「反転して1を足す」とうまくいくのでしょうか。ビットを反転した値は「1の補数」と呼ばれ、元の数と足すとすべてのビットが1になります。8ビットなら「1111 1111」、つまり255です。ここにさらに1を足すと256になり、8ビットの枠を超えて桁あふれし、結果は0に戻ります。足すと0になる相手こそが負の数なので、反転して1を足した値が、ちょうど符号を反転させた数になるわけです。

この一連の流れは、頭で追うよりも実際にビットを操作してみるのが近道です。ビット演算電卓でNOT(反転)を実行し、その結果に1を足して、確かに符号が反転することを確かめてみてください。

符号ビットとビット幅・表せる範囲

2の補数では、ビット列の最上位ビット(一番左のビット)が符号ビットの役割を果たします。この符号ビットが0なら0以上の数、1なら負の数です。ただし符号付き絶対値とは違い、符号ビットは単なる目印ではなく、数の大きさを決める計算にもそのまま組み込まれています。

表せる数の範囲は、ビット幅によって決まります。nビットの2の補数では、-2の(n-1)乗 から +2の(n-1)乗 - 1 までを表現できます。負の側が1だけ広いのは、ゼロが正の側に含まれるためです。代表的なビット幅での範囲を整理すると次のようになります。

ビット幅表せる範囲(符号付き)
8ビット-128 〜 127
16ビット-32,768 〜 32,767
32ビット-2,147,483,648 〜 2,147,483,647
64ビット約 -9.2×10^18 〜 9.2×10^18

プログラミング言語の「int」や「long」といった型の最大値・最小値が、これらの範囲とぴったり一致しているのに気づくでしょう。たとえば32ビット整数の上限「2,147,483,647」は、多くのシステムで見かける馴染みの深い数字です。同じビット列でも、符号なし(0以上のみ)として読むか、符号付き(2の補数)として読むかで意味が変わる点には注意が必要です。基数変換ツールで同じ2進数を符号あり・なしの両方で眺めてみると、この違いが立体的に理解できます。

オーバーフローと注意点

2の補数で表せる範囲には上限と下限があるため、計算結果がその枠を超えるとオーバーフローが起こります。8ビットの符号付き整数で最大値127に1を足すと、ビット列は「0111 1111」から「1000 0000」へと変化し、これは2の補数では-128と読まれます。つまり最大値を超えた瞬間、いきなり最小値へ一周して飛んでしまうのです。

このように数が輪の端で反対側へワープする現象をラップアラウンドと呼びます。意図しないオーバーフローは、ゲームのスコアがマイナスになったり、時間の計算が破綻したりといった、現実の不具合の原因になります。歴史的に有名なバグの多くも、この整数の範囲超えに起因しています。

  • 足し算・掛け算で範囲を超える:大きな正の数同士を足すと、結果が負に転じることがあります。
  • 最小値の符号反転:8ビットの-128を反転して1を足すと-128のまま、という特殊なケースがあります。負の側が1だけ広いことによる現象です。

対策としては、十分に大きいビット幅の型を選ぶ、計算前に範囲を検査する、桁あふれを検出してくれる言語機能を使う、といった方法があります。ビット演算電卓でビット幅を切り替えながら境界付近の値を計算すると、どのタイミングで値が一周するのかを目で確認できます。

手を動かして理解する

2の補数は、文章を読むだけではなかなか腑に落ちにくいテーマです。実際にビットを反転させ、1を足し、符号が変わる様子を自分の目で見ることが、理解への一番の近道になります。次の手順で試してみてください。

  • 基数変換ツールで、好きな正の整数を2進数に変換する。
  • ビット演算電卓でその2進数にNOT(反転)をかけ、結果に1を足す。
  • 得られたビット列を、符号付きの10進数として読み直し、符号が反転していることを確認する。

この往復を何度か繰り返すと、「反転して1を足す」という操作が、なぜちょうどマイナスを意味するのかが感覚としてつかめてきます。2の補数は、限られたビットだけで負の数とゼロを過不足なく表し、足し算と引き算を同じ仕組みで処理するための、よくできた工夫なのです。

なお本記事は一般的な情報の提供を目的としたものです。整数型の正確なビット幅やオーバーフロー時の挙動は、プログラミング言語や処理系によって異なる場合があります。実際の開発では、お使いの言語やプラットフォームの最新の公式仕様・ドキュメントを必ず確認してください。

よくある質問

2の補数とは何ですか?

2の補数とは、コンピュータが0と1のビットだけで負の整数を表すための方式です。一定のビット幅の中で「足すと桁あふれして0に戻る相手」をその数の負の値とみなします。最上位ビットが1なら負、0なら0以上の数を表し、現代のほぼすべてのコンピュータが整数の表現に採用しています。

2の補数はどうやって作りますか?

すべてのビットを反転(0と1を入れ替え)して、その結果に1を足すだけです。たとえば8ビットの3(0000 0011)を反転すると1111 1100になり、1を足すと1111 1101となって、これが-3を表します。同じ操作をもう一度行うと元の値に戻ります。

なぜビットを反転して1を足すと負の数になるのですか?

ビットを反転した値(1の補数)に元の数を足すと全ビットが1になり、8ビットなら255です。これにさらに1を足すと256になり、ビット幅を超えて桁あふれし0に戻ります。足して0になる相手こそが負の数なので、反転して1を足した値がちょうど符号を反転させた数になります。

8ビットや32ビットで表せる数の範囲は?

nビットの2の補数では-2の(n-1)乗から+2の(n-1)乗-1までを表せます。8ビットは-128〜127、16ビットは-32,768〜32,767、32ビットは-2,147,483,648〜2,147,483,647です。負の側が1だけ広いのは、ゼロが正の側に含まれるためです。

WAZA TOOLSのビット演算ツールはデータを送信しますか?

WAZA TOOLSのビット演算電卓や基数変換ツールはすべてブラウザ内で処理され、入力した値がサーバーに送信・保存されることはありません。スマートフォンでも利用でき、何度でも無料でビットの反転や基数変換を試せます。