Overview

Description

Boost.Decimal is an implementation of IEEE 754 and ISO/IEC DTR 24733 Decimal Floating Point numbers. The library is header-only, has no dependencies, and requires C++14.

Motivation

Current C++ floating point types store the significand (often incorrectly referred to as the mantissa) as binary digits. Famously this leads to representation errors: https://0.30000000000000004.com. Decimal floating point numbers avoid this issue by storing the significand in base-10 (decimal). The other major difference between binary and decimal floating point types is that the latter allows for multiple representations of the same number. For example 1e5 could also be stored as 0.1e6, 0.01e7, so on and so forth. These are referred to as cohorts which binary does not have as there is only one way to represent each number in binary floating point.

Use Cases

The use case for Decimal Floating Point numbers is where rounding errors are significantly impactful such as finance. In applications where integer or fixed-point arithmetic are used to combat this issue Decimal Floating Point numbers can provide a significantly greater range of values. For example, while a fixed-point representation that allocates 8 decimal digits and 2 decimal places can represent the numbers 123456.78, 8765.43, 123.00, and so on, a floating-point representation with 8 decimal digits could also represent 1.2345678, 1234567.8, 0.000012345678, 12345678000000000, and so on.

Supported Compilers

Boost.Decimal is tested natively on Ubuntu (x86_64, s390x, and aarch64), macOS (x86_64, and Apple Silicon), and Windows (x32 and x64); as well as emulated PPC64LE and STM32 using QEMU with the following compilers:

  • GCC 7 and later

  • Clang 6 and later

  • Visual Studio 2017 and later

  • Intel OneAPI DPC++

Tested on Github Actions and Drone. Coverage can be found on Codecov.

Basic Usage

#include <boost/decimal.hpp>
#include <iostream>
#include <iomanip>

int main()
{
    using namespace boost::decimal;

    // Outputs 0.30000000000000004
    std::cout << std::setprecision(17) << 0.1 + 0.2;

    // Construct the two decimal values
    constexpr decimal64 a {1, -1}; // 1e-1 or 0.1
    constexpr decimal64 b {2, -1}; // 2e-1 or 0.2

    // Outputs 0.30000000000000000
    std::cout << a + b << std::endl;

    return 0;
}

API Reference

Types

Structures and Classes

Enums

  • None

Constants

  • None

Macros

MD5

This library supports MD5 as described in RFC 1321. There is a wide range of acceptable inputs for the base md5 function:

Hashing Functions

namespace boost {
namespace crypt {

uisng return_type = boost::crypt::array<uint8_t, 16>;

BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const char* str) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const char* str, size_t len) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const unsigned char* str) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const unsigned char* str, size_t len) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const char16_t* str) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const char16_t* str, size_t len) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const char32_t* str) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const char32_t* str, size_t len) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const wchar_t* str) noexcept -> return_type;

BOOST_CRYPT_GPU_ENABLED constexpr auto md5(const wchar_t* str, size_t len) noexcept -> return_type;

inline auto md5(const std::string& str) noexcept -> return_type;

inline auto md5(const std::u16string& str) noexcept -> return_type;

inline auto md5(const std::u32string& str) noexcept -> return_type;

inline auto md5(const std::wstring& str) noexcept -> return_type;

#ifdef BOOST_CRYPT_HAS_STRING_VIEW

inline auto md5(std::string_view str) noexcept -> return_type;

inline auto md5(std::u16string_view str) noexcept -> return_type;

inline auto md5(std::u32string_view str) noexcept -> return_type;

inline auto md5(std::wstring_view str) noexcept -> return_type;

#endif // BOOST_CRYPT_HAS_STRING_VIEW

} //namespace crypt
} //namespace boost

File Hashing Functions

We also have the ability to scan files and return the MD5 value:

namespace boost {
namespace crypt {

uisng return_type = boost::crypt::array<uint8_t, 16>;

inline auto md5_file(const char* filepath) noexcept -> return_type;

inline auto md5_file(const std::string& filepath) noexcept -> return_type;

inline auto md5_file(std::string_view filepath) noexcept -> return_type;

} // namespace crypt
} // namespace boost

Hashing Object

Lastly, there is also the ability to create a MD5 hashing object and feed it bytes as the user parses them. This class does not use any dynamic memory allocation.

namespace boost {
namespace crypt {

class md5_hasher
{
    init();

    template <typename ByteType>
    BOOST_CRYPT_GPU_ENABLED constexpr auto process_byte(ByteType byte) noexcept -> void;

    template <typename ForwardIter>
    BOOST_CRYPT_GPU_ENABLED constexpr auto process_bytes(ForwardIter buffer, size_t byte_count) noexcept -> void;

    constexpr auto get_digest() noexcept -> boost::crypt::array<boost::crypt::uint8_t, 16>;
};

} // namespace crypt
} // namespace boost

Configuration Macros

User Configurable Macros

The following configuration macros are available:

  • None at this time

Automatic Configuration Macros

  • BOOST_CRYPT_HAS_STRING_VIEW: This is defined when compiling with at least C++17 and your standard library has a complete implementation of <string_view>.

References

The following books, papers and blog posts serve as the basis for the algorithms used in the library:

This documentation is copyright 2024 Matt Borland and Chris Kormanyos and is distributed under the Boost Software License, Version 1.0.