C言語で2の補数を求めるプログラム|1の補数からの計算方法とサンプルコード
コンピュータ内部では、負の整数を表現するために「2の補数」が広く使われています。本記事では、与えられた2進数に対して2の補数を求めるC言語のプログラムを、考え方(アルゴリズム)から実行結果までわかりやすく解説します。
2の補数とは
2の補数とは、ある2進数の各ビットを反転させた「1の補数」に1を加えた値のことです。減算を加算として処理できるため、多くのCPUが負の数の表現に採用している重要な概念です。
2の補数を求める2つの方法
与えられた2進数の2の補数は、次のいずれかの方法で計算できます。
- 方法1: まず与えられた2進数を1の補数に変換し、その結果に1を加算します。
- 方法2: 最下位ビット(LSB)側から見て、最初に「1」が現れる位置までのビット(その「1」自身を含む)はそのまま残し、それより上位のすべてのビットを反転します。
1の補数を求めるロジック
1の補数は非常にシンプルで、入力された2進数の各桁について「0」なら「1」へ、「1」なら「0」へと反転するだけです。
for(i = 0; i < SIZE; i++){
if(num[i] == '0'){
one[i] = '1';
}
else if(num[i] == '1'){
one[i] = '0';
}
}
one[SIZE] = '\0';
printf("Ones' complement of binary number %s is %s\n", num, one);
2の補数を求めるロジック
2の補数は、1の補数に1を足す処理として実装できます。最下位ビットから順に見ていき、繰り上がり(carry)を管理しながら各ビットを決定します。
for(i = SIZE - 1; i >= 0; i--){
if(one[i] == '1' && carry == 1){
two[i] = '0';
}
else if(one[i] == '0' && carry == 1){
two[i] = '1';
carry = 0;
} else {
two[i] = one[i];
}
}
two[SIZE] = '\0';
printf("Two's complement of binary number %s is %s\n", num, two);
C言語によるサンプルプログラム
以下は、8ビットの2進数を入力として受け取り、1の補数と2の補数を両方出力する完全なCプログラムです。
#include<stdio.h>
#include<stdlib.h>
#define SIZE 8
int main(){
int i, carry = 1;
char num[SIZE + 1], one[SIZE + 1], two[SIZE + 1];
printf("Enter the binary number\n");
gets(num);
/* 1の補数を計算 */
for(i = 0; i < SIZE; i++){
if(num[i] == '0'){
one[i] = '1';
}
else if(num[i] == '1'){
one[i] = '0';
}
}
one[SIZE] = '\0';
printf("Ones' complement of binary number %s is %s\n", num, one);
/* 1の補数に1を加えて2の補数を計算 */
for(i = SIZE - 1; i >= 0; i--){
if(one[i] == '1' && carry == 1){
two[i] = '0';
}
else if(one[i] == '0' && carry == 1){
two[i] = '1';
carry = 0;
}
else{
two[i] = one[i];
}
}
two[SIZE] = '\0';
printf("Two's complement of binary number %s is %s\n", num, two);
return 0;
}
実行結果
上記のプログラムを実行すると、次のような出力が得られます。ここでは「1000010」を入力した例を示します。
Enter the binary number 1000010 Ones' complement of binary number 1000010 is 0111101 Two's complement of binary number 1000010 is 0111110
補足:gets() の使用について
このサンプルでは入力に gets() を使用していますが、gets() はバッファオーバーフローを引き起こす危険性があるため、現在のC標準(C11以降)では廃止されています。実際の開発では、fgets(num, sizeof(num), stdin) のように安全な関数を使うことを強くおすすめします。
-
Javaで数値がフィボナッチ数かどうかを判定する方法|完全平方数を使ったチェックプログラム
ある整数がフィボナッチ数(0, 1, 1, 2, 3, 5, 8, 13, 21…と続く数列に含まれる数)であるかどうかは、実際に数列を生成しなくても、数学的な性質を利用することで効率的に判定できます。 判定の原理:完全平方数の性質 有名な定理によると、n がフィボナッチ数であるのは、「5n² + 4」または「5n² − 4」のどちらか一方が完全平方数になる場合、かつその場合に限ることが証明されています。これを利用すると、O(1) に近い計算量でフィボナッチ数かどうかをチェックできます。 フィボナッチ数判定のJavaプログラム 以下が、与えられた数値がフィボナッチ数かどうかをチェックするJav
-
Pythonで2つの日付の間の日数を求める方法
2つの日付の間の日数を求めるには、Pythonの標準ライブラリである datetime モジュールを使用します。datetime モジュールには日付を扱うための date クラスが用意されており、dateオブジェクト同士を減算すると、その差が timedelta オブジェクトとして返されます。このオブジェクトの days 属性を参照することで、日数を簡単に取得できます。手順1:必要なライブラリをインポートするまず、datetime モジュールから date クラスをインポートします。from datetime import date手順2:dateオブジェクトを作成する次に、日数を計算したい2