C++ での Boost ライブラリの使い方

胡金庫 2023年10月12日
  1. Boost MultiprecisionLibrary を使用して高精度の計算を実行する
  2. Boost の循環バッファデータ構造を STL 準拠のコンテナとして使う
C++ での Boost ライブラリの使い方

この記事では、C++ で Boost ライブラリを利用する方法を説明します。

Boost MultiprecisionLibrary を使用して高精度の計算を実行する

Boost は、C++ ライブラリのオープンソースライセンスコレクションであり、汎用プログラミングから、画像処理や分散メモリ並列処理などのドメイン固有ライブラリまで、さまざまなツールを提供します。数十の個別のライブラリが含まれており、そのうちのいくつかは最近の STL バージョンに組み込まれています。

これらのライブラリは広範囲にわたってピアレビューされており、オープンソースまたは商用プロジェクト向けに高品質で信頼性の高いコードを提供します。

Boost ライブラリについては膨大な量の資料を取り上げる必要があるため、これらのライブラリがいかに強力であるかの例をいくつか紹介します。Boost ライブラリは通常、ほとんどのオペレーティングシステムに含まれておらず、過去にインストールしたことがない場合は、インストールする必要がある可能性が高いことに注意してください。

まず、高精度の数学的計算を処理する機能を備えた Multiprecision ライブラリから始めます。一般に、数値の C++ 基本型には、最大 64 ビット値の制限されたサイズがあることがわかっています。浮動小数点数を無視しても、組み込み型で表現できる大きな整数は、unsigned の値で最大で約 1,84 * 10^19 になります。これは、多くの実際のアプリケーションにとって、または便利な高精度の電卓アプリを実装したいプログラマーにとってさえ問題になる可能性があります。

Multiprecision ライブラリは、int128_tint256_tint512_tint1024_t などのさまざまな定義済みタイプの整数型を提供します。これらは、固定サイズの整数値を格納するために使用できます。一方、ユーザーが事前に計算の限界を知らない場合は、cpp_int 型を使用して任意精度の整数を格納できます。

これらの型の基本的な使用法を次のコードスニペットに示します。これは、long long 型で表される最大数の乗算を示しています。

#include <boost/multiprecision/cpp_int.hpp>

using std::cout;
using std::endl;
using namespace boost::multiprecision;

int128_t Multiply(long long A, long long B) {
  int128_t ans = (int128_t)A * B;
  return ans;
}

cpp_int Multiply2(long long A, long long B) {
  cpp_int ans = (cpp_int)A * B;
  return ans;
}

int main() {
  long long first = 9223372036854775807;
  long long second = 9223372036854775807;

  cout << "Product of " << first << " * " << second << " = \n"
       << Multiply(first, second) << endl;

  cout << "Product of " << first << " * " << second << " = \n"
       << Multiply2(first, second) << endl;

  return EXIT_SUCCESS;
}

出力:

Product of 9223372036854775807 * 9223372036854775807 =
85070591730234615847396907784232501249
Product of 9223372036854775807 * 9223372036854775807 =
85070591730234615847396907784232501249

Boost の循環バッファデータ構造を STL 準拠のコンテナとして使う

Boost ライブラリが提供するもう 1つの強力なツールは、STL 準拠のコンテナとして実装された循環バッファデータ構造です。循環バッファは、std::list および std::deque に似ていますが、容量が固定されており、オブジェクトの構築時に対応するメモリが割り当てられる点が異なります。

ユーザーは、<boost/circular_buffer.hpp> ヘッダーを含め、boost::circular_buffer 名で新しいオブジェクトを作成する必要があります。後者はテンプレートクラスであり、バッファに格納される要素の型名を受け入れることに注意してください。データ構造は、バッファのそれぞれの端に要素を追加するための push_back/push_front メンバー関数と、要素を削除するための pop_back/pop_front 関数も提供します。

循環バッファがいっぱいになると、新しく追加された要素はバッファの開始から上書きされます。次のコード例は、boost::circular_buffer の一般的な操作を示していますが、クラスの詳細な説明はここにあります。

#include <boost/circular_buffer.hpp>
#include <boost/multiprecision/cpp_int.hpp>

using std::cout;
using std::endl;

template <typename T>
void printBuffer(boost::circular_buffer<T> cbuf) {
  for (const auto &item : cbuf) {
    cout << item << "; ";
  }
  cout << endl;
}

int main() {
  boost::circular_buffer<int> cb(10);

  for (int i = 0; i < 10; ++i) {
    cb.push_back(i);
  }
  printBuffer(cb);

  cout << "cb.back: " << cb.back() << endl;
  cout << "cb.front: " << cb.front() << endl;

  for (int i = 0; i < 5; ++i) {
    cb.push_front(i);
  }
  printBuffer(cb);

  cout << "cb.back: " << cb.back() << endl;
  cout << "cb.front: " << cb.front() << endl;

  cb.pop_back();
  printBuffer(cb);

  cb.pop_front();
  printBuffer(cb);

  return EXIT_SUCCESS;
}

出力:

0; 1; 2; 3; 4; 5; 6; 7; 8; 9;
cb.back: 9
cb.front: 0
4; 3; 2; 1; 0; 0; 1; 2; 3; 4;
cb.back: 4
cb.front: 4
4; 3; 2; 1; 0; 0; 1; 2; 3;
3; 2; 1; 0; 0; 1; 2; 3;
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ Boost