Boost Libraries in C++

  1. Use Boost Multiprecision Library to Conduct High-Precision Calculations
  2. Use Boost Circular Buffer Data Structure as STL Compliant Container

This article will demonstrate how to utilize Boost libraries in C++.

Use Boost Multiprecision Library to Conduct High-Precision Calculations

Boost is an open-source licensed collection of C++ libraries which provide different tools starting from general-purpose programming to domain-specific libraries like image processing or distributed-memory parallelism. It contains several dozen individual libraries, some of which have been incorporated into recent STL versions.

These libraries are extensively peer-reviewed, and they offer high-quality, reliable code for any open-source or commercial project.

Since there is a huge amount of material to be covered about the Boost library, we will only showcase a few examples of how powerful these libraries can be. Mind that the Boost libraries are not usually included on most operating systems, and most likely, you have to install it if you have not done so in the past.

We will start with the Multiprecision library, which brings the ability to handle high-precision mathematical calculations. Generally, we know that C++ fundamental types for numbers have limited sizes with maximum 64-bit values. Even if we ignore the floating-point numbers, large integers that can be represented with built-in types max out at roughly 1,84 * 10^19 for unsigned values. This may be problematic for many real-world applications or even for the programmer who wants to implement a useful high-precision calculator app.

The Multiprecision Library provides different predefined types integer types like int128_t, int256_t, int512_t, and int1024_t, which can be used to store fixed-sized integral values. On the other hand, one can utilize the cpp_int type to store arbitrary precision integers if the user can’t know the limits of calculations in advance.

The basic usage of these types is shown in the following code snippet that demonstrates the multiplication of the largest numbers represented by the long long type.

#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;
}

Output:

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

Use Boost Circular Buffer Data Structure as STL Compliant Container

Another powerful tool provided by the Boost libraries is the circular buffer data structure implemented as the STL compliant container. A circular buffer is similar to std::list and std::deque, except that it has fixed capacity and the corresponding memory is allocated when the object is constructed.

The user should include the <boost/circular_buffer.hpp> header and construct a new object with boost::circular_buffer name. Note that the latter is a template class and accepts a type name of the elements that will be stored in the buffer. The data structure also provides push_back/push_front member functions to add elements to the respective ends of the buffer and pop_back/pop_front functions to remove elements.

When the circular buffer is filled, newly added elements are overwritten from the begging of the buffer. The next code example shows common operations on the boost::circular_buffer, while a detailed description of the class can be found here.

#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;
}

Output:

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;
Contribute
DelftStack is a collective effort contributed by software geeks like you. If you like the article and would like to contribute to DelftStack by writing paid articles, you can check the write for us page.

Related Article - C++ Boost

  • The boost::split Function in C++