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

C++で数値のビットを効率的に反転するプログラムの実装方法

はじめに

このチュートリアルでは、数値のビットを効率的に反転するプログラムについて解説します。

非負の整数が与えられたとき、その数値を2進数形式に変換し、各ビットを反転(0を1に、1を0に)した後、反転結果の10進数の値を出力することを目的とします。

例えば、17は2進数で「10001」と表されます。これを反転すると「01110」となり、10進数では14になります。

アルゴリズムの考え方

ビット反転を効率的に行うには、以下の手順に従います。

  1. 最上位ビットの位置を求める: log2(n) を使って、数値 n の最上位ビット(最も左側の1)の位置 x を取得します。
  2. マスクを作成する: 1 を x ビット左シフトした値に対して m | (m - 1) を計算することで、最上位ビット以下のすべてのビットが1になったマスクを作成します。
  3. XORで反転する: 元の数値とマスクを XOR 演算することで、有効なビット範囲内のすべてのビットを一度に反転できます。

サンプルコード

#include <bits/stdc++.h>
using namespace std;

// 数値のビットを反転する関数
int invert_bit(int n){
    int x = log2(n);
    int m = 1 << x;
    m = m | m - 1;
    n = n ^ m;
    return n;
}

int main(){
    int n = 17;
    cout << invert_bit(n) << endl;
    return 0;
}

出力

14

コードの解説

n = 17 の場合の処理の流れを具体的に見てみましょう。

  • 17 は2進数で「10001」です。
  • log2(17) = 4 なので、最上位ビットの位置は 4 です。
  • m = 1 << 4 = 16(2進数で「10000」)
  • m = 16 | 15 = 31(2進数で「11111」)
  • n = 17 ^ 31 = 14(「10001」^「11111」=「01110」)

このように、XOR演算によって「10001」の各ビットが反転され、「01110」、すなわち10進数の14が得られます。

計算量

このアルゴリズムは log2 の計算とビット演算のみで構成されているため、時間計算量は O(1)、空間計算量も O(1) と非常に効率的です。ループで1ビットずつ反転する方法と比べ、大きな数値でも高速に処理できる点が大きなメリットです。

まとめ

log2 による最上位ビットの検出とビットマスク、XOR演算を組み合わせることで、数値のビット反転を定数時間で実現できます。ビット操作の基礎を理解するのに最適なテクニックなので、ぜひマスターしておきましょう。

  1. C++で数値の累乗を計算する方法:再帰・非再帰プログラムの実装例

    数の累乗とは数の累乗は x^y の形式で表され、x は基数(底)、y は指数を表します。例を見てみましょう。x = 2、y = 10 の場合 x^y = 1024 ここで、x^y は 2^10 を意味します数の累乗は、再帰的プログラムと非再帰的プログラムの2つの方法で計算できます。以下、それぞれの実装方法を詳しく解説します。非再帰プログラムによる累乗の計算まずは、forループを使用した非再帰的なプログラムの例です。サンプルコード#include<iostream>using namespace std;int power(int x, int y) { int i

  2. 数値を逆順に並べ替えるC++プログラムの書き方と解説

    数値の反転とは、その桁の数字を逆の順序に並べ替えて格納することを指します。 例えば、元の数値が6529である場合、出力として9256が表示されます。 以下に、数値を反転させるC++プログラムの例を示します。 サンプルプログラム #include <iostream> using namespace std; int main() { int num = 63972, rev = 0; while(num > 0) { rev = rev*10 + num%10; num = num/10; } cout<