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

C++で整数の1の補数(nビット)を求める方法

1の補数とは

本記事では、整数の「1の補数」を求める方法について解説します。C++には補数演算子(~)が用意されており、これを使えば非常に高速に補数を計算できます。ただし、この演算子は32ビット(4バイト)全体に対して補数を求めてしまうため、ここでは「与えられた数値のビット数分だけの補数」を取得する方法を考えます。

例として、22という数値を取り上げます。22の2進表現は「10110」であり、その1の補数は「01001」、つまり10進数の9になります。では、この値はどのようにして求めればよいのでしょうか。

求め方の手順

まず、対象の数値のビット数を求めます。この値をcとします(22の場合、c = 5)。次に、5桁すべてが1の数「11111」を作成します。これは、1を左へc回シフトした後、1を減算することで実現できます。1を左に5回シフトすると「100000」になり、そこから1を引けば「11111」が得られます。最後に、この「11111」と元の数値「10110」のXOR(排他的論理和)を計算することで、目的の1の補数が求まります。

サンプルコード

#include <iostream>
#include <cmath>
using namespace std;
int findComplement(int n) {
    int bit_count = floor(log2(n))+1;
    int ones = ((1 << bit_count) - 1);
    return ones ^ n;
}
int main() {
    int number = 22;
    cout << "One's Complement of " << number << " is: " << findComplement(number);
}

出力結果

One's Complement of 22 is: 9
  1. 【C++】直前の数値が1の補数と一致するかどうかを判定する方法

    整数 n が与えられたとき、n の直前の数(n − 1)がn の1の補数と一致しているかどうかを判定するのが、この問題の目的です。 具体例で問題を理解する 入力: 12 出力: No 解説: (12)10 = (1100)2 直前の数 11 = (1011)2 12 の1の補数 = (0011)2 入力: 4 出力: Yes 解説: 4 = (100)2 直前の数 3 = (011)2 4 の1の補数 = (011)2 単純なアプローチ 最も素直な方法は、n − 1 を計算し、n の各ビットを反転して得られる1の補数と直接比較することです。し

  2. C++で1つのセットビットを変更して得られる、nより小さい最大の整数

    問題の概要この問題では、整数 n が与えられます。求められているのは、n の2進数表現における「セットビット(1になっているビット)」を1つだけ変更することで作れる数のうち、n より小さい最大の整数を出力することです。具体例を見てみましょう。入力: n = 3 出力: 2 解説: (3)10 = (011)2 セットビットを1つ反転すると、001 と 010 が得られます。このうち大きいのは 010、すなわち 2 です。解き方のアプローチこの問題を解く鍵は、「最も右側にあるセットビット」に注目することです。n より小さくなるようにビットを1つだけ変更するなら、最下位のセットビットを0に反転する