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;