Basic Usage
Construction of Decimal Types
Every decimal type can be constructed in a few ways:
Construction from Coefficient and Exponent
namespace boost {
namespace decimal {
enum class construction_sign
{
negative,
positive
};
template <typename UnsignedInteger, typename Integer>
constexpr decimal32_t(UnsignedInteger coefficient, Integer exponent, construction_sign resultant_sign = construction_sign::positive) noexcept;
template <typename SignedInteger, typename Integer>
constexpr decimal32_t(SignedInteger coefficient, Integer exponent) noexcept;
} // namespace decimal
} // namespace boost
As you can see you are either allowed to pass a signed integer, or specify the signedness of the resulting number, but not both.
This is designed to reduce confusion (e.g. what would be the resulting sign of {-3, 0, construction_sign::negative}?)
boost::decimal::decimal32_t a {1, 1}; // constructs 1e1 = 10
boost::decimal::decimal32_t b {-2, -1}; // constructs -2e-2 or -0.2
boost::decimal::decimal32_t c {2U, -1, construction_sign::negative}; // also constructs -2e-1 or -0.2 (Note: The coefficient must be an unsigned type)
boost::decimal::decimal32_t d {5, 5}; // constructs 5x10^5
boost::decimal::decimal32_t e {1234, -3} // constructs 1.234 or 1234x10^-3
Overflow and underflow are handled the same way that they are with binary floating point numbers i.e. they will construct an infinity or a zero.
boost::decimal::decimal64_t overflow_value {100, 10000}; // Constructs +infinity
boost::decimal::decimal64_t underflow_value {100, -10000}; // Constructs 0
Construction from Integer
A decimal number can be explicitly constructed from an integer. For example:
boost::decimal::decimal32_t f {-4};
Construction from Binary Floating Point
A decimal number can only be explicitly constructed from a floating point type. For example:
boost::decimal::decimal128_t pi {3.14};
Construction from non-finite values (e.g. std::numeric_limits<double>::quiet_NaN()) will yield the same non-finite value in the resulting decimal value.
Overflow or underflow will construct infinity or 0.
| Due to the differences in decimal and binary floating point numbers there may be a difference in the resulting representation in decimal format, and thus it is not recommended to construct from binary floating point numbers |
For more information see: Basic Construction
Fundamental Operations
The fundamental operations of numerical types (e.g. >, ==, +, etc.) are provided for each type, to include mixed type arithmetic (e.g. decimal32_t + decimal64_t), and between integers and decimal types.
For more information see: Promotion and Mixed Decimal Arithmetic.
Rounding
The default rounding mode for all operations is so-called "banker’s rounding", which is to nearest (with ties to even).
Similar to the standard library, the active rounding mode can be changed through floating point environment variables.
For more information see: <cfenv> Support
Using the Library
The entire library can be accessed using the convenience header <boost/decimal.hpp>.
A short example of the basic usage:
// Copyright 2025 Matt Borland
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/decimal.hpp> // This includes the entire decimal library
#include <iostream>
#include <iomanip>
int main()
{
using namespace boost::decimal::literals; // The literals are in their own namespace like std::literals
// First we show the result of 0.1 + 0.2 using regular doubles
std::cout << std::fixed << std::setprecision(17)
<< "Using doubles:\n"
<< "0.1 + 0.2 = " << 0.1 + 0.2 << "\n\n";
// Construct the two decimal values
// We construct using the literals defined by the library
constexpr boost::decimal::decimal64_t a {0.1_DD};
constexpr boost::decimal::decimal64_t b {0.2_DD};
// Now we display the result of the same calculation using decimal64_t
std::cout << "Using decimal64_t:\n"
<< "0.1_DD + 0.2_DD = " << a + b << std::endl;
}
Using doubles: 0.1 + 0.2 = 0.30000000000000004 Using decimal64_t: 0.1_DD + 0.2_DD = 0.3000000000000000