decimal128_t

Description

decimal128_t is the 128-bit version of the decimal interchange format, and has the following properties as defined in IEEE 754-2019 table 3.6

Attribute

values

Storage Width

128 bits

Precision

34 decimal digits

Max exponent

6145

Max Value

9.99999…​e+6145

Smallest Normalized Value

1.0000…​e-6142

Smallest Subnormal Value

1e-6176

Prior to v5.0.0 this type was known as decimal32. This name has been removed in v6.0.0.

The encoding of decimal128_t is in the BID format.

#include <boost/decimal/decimal128_t.hpp>

namespace boost {
namespace decimal {

class decimal128_t {

public:
    using significand_type = detail::uint128;
    using exponent_type = std::uint32_t;
    using biased_exponent_type = std::int32_t;

// Paragraph numbers are from ISO/IEC DTR 24733

// 3.2.4.1 construct/copy/destroy
constexpr decimal128_t() noexcept = default;

// 3.2.4.2 Conversion form floating-point type
template <typename Float>
explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t(Float val) noexcept;

// 3.2.4.3 Conversion from integral type
template <typename Integer>
explicit constexpr decimal128_t(Integer val) noexcept;

// Extension: Construction from (c)string
explicit constexpr decimal128_t(const char* str);

#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW
explicit inline decimal128_t(const std::string& str);
#else
explicit constexpr decimal128_t(std::string_view str);
#endif

template <typename UnsignedIntegral, typename Integral>
constexpr decimal128_t(UnsignedIntegral coeff, Integral exp, bool is_negative = false) noexcept;

template <typename SignedIntegral, typename Integral>
constexpr decimal128_t(SignedIntegral coeff, Integral exp, bool is_negative = false) noexcept;

template <typename Integral>
constexpr decimal128_t& operator=(const Integeral& RHS) noexcept;

// 3.2.4.4 Conversion to integral type
// If the value exceeds the range of the integral,
// or is non-finite std::numeric_limits::max() is returned
explicit constexpr operator int() const noexcept;
explicit constexpr operator unsigned() const noexcept;
explicit constexpr operator long() const noexcept;
explicit constexpr operator unsigned long() const noexcept;
explicit constexpr operator long long() const noexcept;
explicit constexpr operator unsigned long long() const noexcept;

// 3.2.4.5 increment and decrement operators:
constexpr decimal128_t& operator++();
constexpr decimal128_t  operator++(int);
constexpr decimal128_t& operator--();
constexpr decimal128_t  operator--(int);

// 3.2.4.6 compound assignment:
constexpr decimal128_t& operator+=(RHS rhs);
constexpr decimal128_t& operator-=(RHS rhs);
constexpr decimal128_t& operator*=(RHS rhs);
constexpr decimal128_t& operator/=(RHS rhs);

// 3.2.6 Conversion to floating-point type
explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept;
explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept;
explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept;

// The following are available assuming a C++23 compiler that provides the header <stdfloat>
explicit constexpr operator std::float16_t() const noexcept;
explicit constexpr operator std::float32_t() const noexcept;
explicit constexpr operator std::float64_t() const noexcept;
explicit constexpr operator std::bfloat16_t() const noexcept;

explicit constexpr operator decimal32_t() const noexcept;
explicit constexpr operator decimal_fast32_t() const noexcept;
explicit constexpr operator decimal64_t() const noexcept;
explicit constexpr operator decimal_fast64_t() const noexcept;
explicit constexpr operator decimal_fast128_t() const noexcept;

}; // class decimal128_t

} //namespace decimal
} //namespace boost

Operator Behavior

Construction to and from binary floating-point type

// 3.2.2.2 Conversion from floating-point type
template <typename Float>
explicit BOOST_DECIMAL_CXX20_CONSTEXPR decimal128_t(Float val) noexcept;

// 3.2.6 Conversion to floating-point type
explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator float() const noexcept;
explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator double() const noexcept;
explicit BOOST_DECIMAL_CXX20_CONSTEXPR operator long double() const noexcept;

// If C++23 and <stdfloat> are available
explicit constexpr operator std::float16_t() const noexcept;
explicit constexpr operator std::float32_t() const noexcept;
explicit constexpr operator std::float64_t() const noexcept;
explicit constexpr operator std::bfloat16_t() const noexcept;

Construction From Integral Type

// 3.2.2.3 Conversion from integral type
template <typename Integer>
explicit constexpr decimal128_t(Integer val) noexcept;

Constructs a decimal value subject to the current rounding mode (if necessary).

Construction From String

// Extension: Construction from (c)string
explicit constexpr decimal128_t(const char* str);

#ifndef BOOST_DECIMAL_HAS_STD_STRING_VIEW
explicit inline decimal128_t(const std::string& str);
#else
explicit constexpr decimal128_t(std::string_view str);
#endif

Constructs a decimal value that matches str subject to:

  1. If str is a nullptr or of length 0 either:

    1. throw std::runtime_error

    2. Constructs a QNAN in a no exception environment

  2. If str is an invalid string either:

    1. throw std::runtime_error

    2. Constructs a QNAN in a no exception environment

  3. On overflow constructs INF

  4. On underflow constructs 0

  5. Rounds value represented by str according to current rounding mode

Conversion to Integral Type

// 3.2.2.4 Conversion to integral type

explicit constexpr operator int() const noexcept;
explicit constexpr operator unsigned() const noexcept;
explicit constexpr operator long() const noexcept;
explicit constexpr operator unsigned long() const noexcept;
explicit constexpr operator long long() const noexcept;
explicit constexpr operator unsigned long long() const noexcept;

Constructs an integer representation of the decimal value subject to:

  1. If the decimal value is INF returns std::numeric_limits<IntegerType>::max()

  2. If the decimal value is NAN returns std::numeric_limits<IntegerType>::max()

  3. If the decimal value exceeds the range of the IntegerType returns std::numeric_limits<IntegerType>::max()

Increment and Decrement Operators

// 3.2.2.5 increment and decrement operators:
constexpr decimal128_t& operator++();
constexpr decimal128_t  operator++(int);
constexpr decimal128_t& operator--();
constexpr decimal128_t  operator--(int);

Increments/Decrements the decimal value subject to:

  1. If the decimal value is NAN returns QNAN

  2. If the decimal value is INF returns INF

Compound Operators

// 3.2.2.6 compound assignment:
constexpr decimal128_t& operator+=(RHS rhs);
constexpr decimal128_t& operator-=(RHS rhs);
constexpr decimal128_t& operator*=(RHS rhs);
constexpr decimal128_t& operator/=(RHS rhs);

Conversion to Other Decimal Types

explicit constexpr operator decimal32_t() const noexcept;
explicit constexpr operator decimal_fast32_t() const noexcept;
explicit constexpr operator decimal64_t() const noexcept;
explicit constexpr operator decimal_fast64_t() const noexcept;
explicit constexpr operator decimal_fast128_t() const noexcept;

Conversion to decimal_fast128_t is lossless in all cases.

Conversion to all other decimal types is subject to:

  1. Current rounding mode if the number of digits exceeds the precision of the target type.

  2. Overflow constructs INF.

  3. Underflow constructs 0.

Non-Member Operator Behavior

See here for behavior of non-member operators.