C++ 中的 Boost 库

Jinku Hu 2023年1月30日 2021年10月2日
  1. 使用 Boost 多精度库进行高精度计算
  2. 使用 Boost 循环缓冲区数据结构作为符合 STL 的容器
C++ 中的 Boost 库

本文将演示如何在 C++ 中使用 Boost 库。

使用 Boost 多精度库进行高精度计算

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 库提供的另一个强大工具是作为 STL 兼容容器实现的循环缓冲区数据结构。循环缓冲区类似于 std::liststd::deque,不同之处在于它具有固定容量,并且在构造对象时分配相应的内存。

用户应该包含 <boost/circular_buffer.hpp> 标头并构造一个名为 boost::circular_buffer 的新对象。请注意,后者是一个模板类,并接受将存储在缓冲区中的元素的类型名称。该数据结构还提供了 push_back/push_front 成员函数以将元素添加到缓冲区的各个末端,以及 pop_back/pop_front 成员函数以删除元素。

当循环缓冲区被填满时,新添加的元素会从缓冲区的请求中被覆盖。下一个代码示例显示了对 boost::circular_buffer 的常见操作,而该类的详细描述可以在这里找到。

#include <boost/multiprecision/cpp_int.hpp>
#include <boost/circular_buffer.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;
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相关文章 - C++ Boost