C++ 中的 Boost 庫
本文將演示如何在 C++ 中使用 Boost 庫。
使用 Boost 多精度庫進行高精度計算
Boost 是 C++ 庫的開源許可集合,它提供從通用程式設計到特定領域庫(如影象處理或分散式記憶體並行)的不同工具。它包含幾十個單獨的庫,其中一些已被合併到最近的 STL 版本中。
這些庫都經過了廣泛的同行評議,它們為任何開源或商業專案提供了高質量、可靠的程式碼。
由於有大量關於 Boost 庫的資料需要介紹,我們將僅展示這些庫的強大功能的幾個示例。請注意,大多數作業系統中通常不包含 Boost 庫,而且很可能,如果你過去沒有安裝它,則必須安裝它。
我們將從 Multiprecision
庫開始,它具有處理高精度數學計算的能力。通常,我們知道數字的 C++ 基本型別的大小有限,最大為 64 位值。即使我們忽略浮點數,對於 unsigned
值,可以用內建型別表示的大整數最大約為 1,84 * 10^19
。對於許多實際應用程式,甚至對於想要實現有用的高精度計算器應用程式的程式設計師來說,這可能是個問題。
Multiprecision
庫提供了不同的預定義型別整數型別,如 int128_t
、int256_t
、int512_t
和 int1024_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 庫提供的另一個強大工具是作為 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;