Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C/C++の算術加算でオーバーフローが起きる仕組み|2の補数による検出方法

2の補数とは

2の補数(2's Complement)は、コンピュータアーキテクチャにおいて最も広く採用されている符号付き整数の表現方式です。

Nビットの2の補数システムでは、-2n-1 ~ 2n-1-1 の範囲の整数を表現できます。具体例は以下の通りです。

  • 4ビットの場合: -8 ~ 7
  • 5ビットの場合: -16 ~ 15

オーバーフローが発生する仕組み

2つのNビットの2の補数を加算した結果が、Nビットで表現できる範囲を超えると「オーバーフロー」が発生します。

コンピュータ内部には固定長のNビットレジスタが搭載されており、2つのNビット数の加算結果は最大でもN+1ビットになります。この余分な1ビットはキャリーフラグに格納されますが、キャリーが発生しても必ずしもオーバーフローを意味するわけではない点に注意が必要です。

オーバーフローの検出方法

加算時にオーバーフローが発生するのは、主に次のようなケースです。

  • 負の数同士を加算した結果が正になる場合
  • 正の数同士を加算した結果が負になる場合

そのため、2つのオペランドと演算結果それぞれの最上位ビット(MSB:Most Significant Bit)を確認すれば、オーバーフローを検出できます。

しかし、3ビットコンパレータを実装しなくても、MSBからのキャリーイン(Carry-in)とキャリーアウト(Carry-out)だけを比較する2ビット構成でもオーバーフロー検出は可能です。ここでは、2の補数によるNビット加算を例に考えてみましょう。

C/C++の算術加算でオーバーフローが起きる仕組み|2の補数による検出方法


オーバーフローは「キャリーインとキャリーアウトが一致しない」場合に発生します。この条件が成り立つ理由を、以下の分析で詳しく見ていきます。

C/C++の算術加算でオーバーフローが起きる仕組み|2の補数による検出方法


ケース1: 2つの数のMSBがどちらも0の場合、両方とも正の数です。ここでキャリーインが1になると、結果のMSBが1となり、結果が負であることを示します(=オーバーフロー)。このときキャリーアウトは0です。キャリーインとキャリーアウトが一致しないため、オーバーフローが発生していることが分かります。

ケース2: 2つの数のMSBがどちらも1の場合、両方とも負の数です。ここでキャリーインが0になると、結果のMSBが0となり、結果が正であることを示します(=オーバーフロー)。このときキャリーアウトは1です。こちらもキャリーインとキャリーアウトが一致しないため、オーバーフローが発生しています。

つまり、MSBにおけるキャリーインとキャリーアウトを確認するだけで、オーバーフローを確実に検出できるのです。

C/C++の算術加算でオーバーフローが起きる仕組み|2の補数による検出方法


上図のように、XORゲートを使えばオーバーフロー検出回路を簡単に実装できます。キャリーインとキャリーアウトが異なる場合にXORの出力が1となるため、その出力をオーバーフローフラグとして利用できるのです。

  1. 三角マッチ棒数を求めるC/C++プログラムの解説と実装例

    三角マッチ棒数とはマッチ棒を正三角形の形に並べて作った三角形のことを「三角マッチ棒数(Triangular Matchstick Number)」と呼びます。三角マッチ棒数とは、そのマッチ棒の三角形を作るために必要なマッチ棒の本数を指します。問題の概要この問題では、マッチ棒で作るピラミッドの段数 X が与えられます。そして、X 段のマッチ棒ピラミッドを構成するために必要なマッチ棒の最小総本数を出力するプログラムを作成するのが課題です。概念をより明確にするために、具体例を見てみましょう。入力: 7 出力: 84解法の考え方この問題は、三角数(Triangular Number)の拡張として考える

  2. C/C++でn番目のカタラン数を求めるプログラム

    カタラン数(Catalan numbers)とは、組み合わせ論におけるさまざまな数え上げ問題に現れる自然数の数列です。特に、再帰的に定義される対象の個数を数える場面で頻繁に登場することで知られています。カタラン数の主な性質ディック語(Dyck word)との関係Cn は、長さ 2n のディック語の総数を表します。ディック語とは、n 個の X と n 個の Y から構成され、文字列のどの先頭部分を見ても Y の数が X の数を超えない文字列のことです。例えば、長さ 6 のディック語は次の通りです。XXXYYY XYXXYY XYXYXY XXYYXY XXYXYY.正しい括弧の対応付けX を開き