Decimal Types

Synopsis of header <boost/decimal.hpp>

// Paragraph numbers are from ISO/IEC DTR 24733

namespace boost {
namespace decimal {

// 3.2.2 class decimal32_t:
class decimal32_t;

// 3.2.3 class decimal64_t:
class decimal64_t;

// 3.2.4 class decimal128_t:
class decimal128_t;

// 3.2.7 unary arithmetic operators:
constexpr decimal32_t  operator+(decimal32_t rhs) noexcept;
constexpr decimal64_t  operator+(decimal64_t rhs) noexcept;
constexpr decimal128_t operator+(decimal128_t rhs) noexcept;

constexpr decimal32_t  operator-(decimal32_t rhs) noexcept;
constexpr decimal64_t  operator-(decimal64_t rhs) noexcept;
constexpr decimal128_t operator-(decimal128_t rhs) noexcept;

// 3.2.8 binary arithmetic operators:
// LHS and RHS can be any integer or decimal type

constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal32_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal64_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal128_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator+(decimal32_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator+(decimal64_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator+(decimal128_t lhs, RHS rhs) noexcept;

constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal32_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal64_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal128_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator-(decimal32_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator-(decimal64_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator-(decimal128_t lhs, RHS rhs) noexcept;

constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal32_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal64_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal128_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator*(decimal32_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator*(decimal64_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator*(decimal128_t lhs, RHS rhs) noexcept;

constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal32_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal64_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal128_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator/(decimal32_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator/(decimal64_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator/(decimal128_t lhs, RHS rhs) noexcept;

// 3.2.9 comparison operators:
// LHS and RHS can be any integer or decimal type

constexpr bool operator==(LHS lhs, decimal32_t rhs) noexcept;
constexpr bool operator==(LHS lhs, decimal64_t rhs) noexcept;
constexpr bool operator==(LHS lhs, decimal128_t rhs) noexcept;
constexpr bool operator==(decimal32_t lhs, RHS rhs) noexcept;
constexpr bool operator==(decimal64_t lhs, RHS rhs) noexcept;
constexpr bool operator==(decimal128_t lhs, RHS rhs) noexcept;
constexpr bool operator!=(LHS lhs, decimal32_t rhs) noexcept;
constexpr bool operator!=(LHS lhs, decimal64_t rhs) noexcept;
constexpr bool operator!=(LHS lhs, decimal128_t rhs) noexcept;
constexpr bool operator!=(decimal32_t lhs, RHS rhs) noexcept;
constexpr bool operator!=(decimal64_t lhs, RHS rhs) noexcept;
constexpr bool operator!=(decimal128_t lhs, RHS rhs) noexcept;
constexpr bool operator<(LHS lhs, decimal32_t rhs) noexcept;
constexpr bool operator<(LHS lhs, decimal64_t rhs) noexcept;
constexpr bool operator<(LHS lhs, decimal128_t rhs) noexcept;
constexpr bool operator<(decimal32_t lhs, RHS rhs) noexcept;
constexpr bool operator<(decimal64_t lhs, RHS rhs) noexcept;
constexpr bool operator<(decimal128_t lhs, RHS rhs) noexcept;
constexpr bool operator<=(LHS lhs, decimal32_t rhs) noexcept;
constexpr bool operator<=(LHS lhs, decimal64_t rhs) noexcept;
constexpr bool operator<=(LHS lhs, decimal128_t rhs) noexcept;
constexpr bool operator<=(decimal32_t lhs, RHS rhs) noexcept;
constexpr bool operator<=(decimal64_t lhs, RHS rhs) noexcept;
constexpr bool operator<=(decimal128_t lhs, RHS rhs) noexcept;
constexpr bool operator>(LHS lhs, decimal32_t rhs) noexcept;
constexpr bool operator>(LHS lhs, decimal64_t rhs) noexcept;
constexpr bool operator>(LHS lhs, decimal128_t rhs) noexcept;
constexpr bool operator>(decimal32_t lhs, RHS rhs) noexcept;
constexpr bool operator>(decimal64_t lhs, RHS rhs) noexcept;
constexpr bool operator>(decimal128_t lhs, RHS rhs) noexcept;
constexpr bool operator>=(LHS lhs, decimal32_t rhs) noexcept;
constexpr bool operator>=(LHS lhs, decimal64_t rhs) noexcept;
constexpr bool operator>=(LHS lhs, decimal128_t rhs) noexcept;
constexpr bool operator>=(decimal32_t lhs, RHS rhs) noexcept;
constexpr bool operator>=(decimal64_t lhs, RHS rhs) noexcept;
constexpr bool operator>=(decimal128_t lhs, RHS rhs) noexcept;

// If C++20 is available
// LHS and RHS can be any integer or decimal type

constexpr std::partial_ordering operator<=>(decimal32_t lhs, RHS rhs) noexcept;
constexpr std::partial_ordering operator<=>(decimal64_t lhs, RHS rhs) noexcept;
constexpr std::partial_ordering operator<=>(decimal128_t lhs, RHS rhs) noexcept;
constexpr std::partial_ordering operator<=>(LHS lhs, decimal32_t rhs) noexcept;
constexpr std::partial_ordering operator<=>(LHS lhs, decimal64_t rhs) noexcept;
constexpr std::partial_ordering operator<=>(LHS lhs, decimal128_t rhs) noexcept;

// 3.2.10 Formatted input:
// These functions are locale dependent
template <typename charT, typename traits>
std::basic_istream<charT, traits>&
operator>>(std::basic_istream<charT, traits>& is,
decimal32_t& d);

template <typename charT, typename traits>
std::basic_istream<charT, traits>&
operator>>(std::basic_istream<charT, traits> & is,
decimal64_t& d);

template <typename charT, typename traits>
std::basic_istream<charT, traits>&
operator>>(std::basic_istream<charT, traits> & is,
decimal128_t& d);

// 3.2.11 Formatted output:
// These functions are locale dependent
template <typename charT, typename traits>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
decimal32_t d);

template <typename charT, typename traits>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
decimal64_t d);

template <typename charT, typename traits>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
decimal128_t d);

} //namespace decimal
} //namespace boost

3.2.8 Note

In the event of binary arithmetic between a non-decimal type and a decimal type the arithmetic will occur between the native types, and the result will be returned as the same type as the decimal operand. (e.g. decimal32_t * uint64_t → decimal32_t)

In the event of binary arithmetic between two decimal types the result will be the higher precision type of the two (e.g. decimal64_t + decimal32_t → decimal64_t)

Operator Behaviors

Unary Plus

// 3.2.7 unary arithmetic operators:
constexpr decimal32_t  operator+(decimal32_t rhs) noexcept;
constexpr decimal64_t  operator+(decimal64_t rhs) noexcept;
constexpr decimal128_t operator+(decimal128_t rhs) noexcept;

Returns rhs unmodified in all cases.

Unary Minus

constexpr decimal32_t  operator-(decimal32_t rhs) noexcept;
constexpr decimal64_t  operator-(decimal64_t rhs) noexcept;
constexpr decimal128_t operator-(decimal128_t rhs) noexcept;

Returns negated rhs in all cases.

Addition

// 3.2.8 binary arithmetic operators:
// LHS and RHS can be any integer or decimal type

constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal32_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal64_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator+(LHS lhs, decimal128_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator+(decimal32_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator+(decimal64_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator+(decimal128_t lhs, RHS rhs) noexcept;

Returns the result of lhs + rhs subject to:

  1. If either lhs or rhs are NAN, returns QNAN

  2. If lhs and rhs are INF of opposite sign, returns QNAN

  3. If either lhs or rhs are INF, returns INF of same sign

  4. If lhs + rhs overflows, returns INF

  5. If lhs + rhs underflows, returns 0

Subtraction

// 3.2.8 binary arithmetic operators:
// LHS and RHS can be any integer or decimal type

constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal32_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal64_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator-(LHS lhs, decimal128_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator-(decimal32_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator-(decimal64_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator-(decimal128_t lhs, RHS rhs) noexcept;

Returns the result of lhs - rhs subject to:

  1. If either lhs or rhs are NAN, returns QNAN

  2. If lhs and rhs are INF of opposite sign, returns QNAN

  3. If either lhs or rhs are INF, returns INF of same sign

  4. If lhs - rhs overflows, returns INF

  5. If lhs - rhs underflows, returns 0

Multiplication

// 3.2.8 binary arithmetic operators:
// LHS and RHS can be any integer or decimal type

constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal32_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal64_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator*(LHS lhs, decimal128_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator*(decimal32_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator*(decimal64_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator*(decimal128_t lhs, RHS rhs) noexcept;

Returns the result of lhs * rhs subject to:

  1. If either lhs or rhs are NAN, returns QNAN

  2. If either lhs or rhs are INF and the other is 0, returns QNAN

  3. If either lhs or rhs are INF, returns INF of same sign

  4. If lhs * rhs overflows, returns INF

  5. If lhs * rhs underflows, returns 0

Division

// 3.2.8 binary arithmetic operators:
// LHS and RHS can be any integer or decimal type

constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal32_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal64_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator/(LHS lhs, decimal128_t rhs) noexcept;
constexpr /* see 3.2.8 */ operator/(decimal32_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator/(decimal64_t lhs, RHS rhs) noexcept;
constexpr /* see 3.2.8 */ operator/(decimal128_t lhs, RHS rhs) noexcept;

Returns the result of lhs / rhs subject to:

  1. If either lhs or rhs are NAN, returns QNAN

  2. If lhs is INF:

    1. Returns QNAN if rhs is INF

    2. Returns INF if rhs is not INF

  3. If rhs is 0 returns INF

  4. If rhs is INF returns 0

  5. If lhs / rhs overflows, returns INF

  6. If lhs / rhs underflows, returns 0

Comparison Operators

// 3.2.9 comparison operators:
// LHS and RHS can be any integer or decimal type

constexpr bool operator==(LHS lhs, decimal32_t rhs) noexcept;
constexpr bool operator==(LHS lhs, decimal64_t rhs) noexcept;
constexpr bool operator==(LHS lhs, decimal128_t rhs) noexcept;
constexpr bool operator==(decimal32_t lhs, RHS rhs) noexcept;
constexpr bool operator==(decimal64_t lhs, RHS rhs) noexcept;
constexpr bool operator==(decimal128_t lhs, RHS rhs) noexcept;
constexpr bool operator!=(LHS lhs, decimal32_t rhs) noexcept;
constexpr bool operator!=(LHS lhs, decimal64_t rhs) noexcept;
constexpr bool operator!=(LHS lhs, decimal128_t rhs) noexcept;
constexpr bool operator!=(decimal32_t lhs, RHS rhs) noexcept;
constexpr bool operator!=(decimal64_t lhs, RHS rhs) noexcept;
constexpr bool operator!=(decimal128_t lhs, RHS rhs) noexcept;
constexpr bool operator<(LHS lhs, decimal32_t rhs) noexcept;
constexpr bool operator<(LHS lhs, decimal64_t rhs) noexcept;
constexpr bool operator<(LHS lhs, decimal128_t rhs) noexcept;
constexpr bool operator<(decimal32_t lhs, RHS rhs) noexcept;
constexpr bool operator<(decimal64_t lhs, RHS rhs) noexcept;
constexpr bool operator<(decimal128_t lhs, RHS rhs) noexcept;
constexpr bool operator<=(LHS lhs, decimal32_t rhs) noexcept;
constexpr bool operator<=(LHS lhs, decimal64_t rhs) noexcept;
constexpr bool operator<=(LHS lhs, decimal128_t rhs) noexcept;
constexpr bool operator<=(decimal32_t lhs, RHS rhs) noexcept;
constexpr bool operator<=(decimal64_t lhs, RHS rhs) noexcept;
constexpr bool operator<=(decimal128_t lhs, RHS rhs) noexcept;
constexpr bool operator>(LHS lhs, decimal32_t rhs) noexcept;
constexpr bool operator>(LHS lhs, decimal64_t rhs) noexcept;
constexpr bool operator>(LHS lhs, decimal128_t rhs) noexcept;
constexpr bool operator>(decimal32_t lhs, RHS rhs) noexcept;
constexpr bool operator>(decimal64_t lhs, RHS rhs) noexcept;
constexpr bool operator>(decimal128_t lhs, RHS rhs) noexcept;
constexpr bool operator>=(LHS lhs, decimal32_t rhs) noexcept;
constexpr bool operator>=(LHS lhs, decimal64_t rhs) noexcept;
constexpr bool operator>=(LHS lhs, decimal128_t rhs) noexcept;
constexpr bool operator>=(decimal32_t lhs, RHS rhs) noexcept;
constexpr bool operator>=(decimal64_t lhs, RHS rhs) noexcept;
constexpr bool operator>=(decimal128_t lhs, RHS rhs) noexcept;

Returns the result of the comparison subject to:

  1. If lhs or rhs returns false

    1. This includes the case where both lhs and rhs are NAN