Conversion
| Capability | dec32 | dec64 | dec128 |
|---|---|---|---|
| String import/export | |||
| Float import/export | |||
| BID raw access | |||
| DPD import/export | |||
| Decompose (sign, coeff, exp) | |||
coefficient() utility |
LIBDECIMAL uses BID as its canonical internal representation for decimal32, decimal64, and decimal128. This is the core design choice: arithmetic, comparisons, formatting, and most constructors operate directly on the raw BID form.
DPD, in contrast, is treated as an interchange encoding. It is fully supported for import/export via explicit wrapper conversions, allowing values to be round-tripped when required. In practice, this means:
- BID is the working format
- DPD is a wire-format companion
A decimal value can be explicitly converted to raw BID or to raw DPD, and constructed back from DPD as needed. Internally, these transitions are handled by impl::bid2dpd() and impl::dpd2bid() specializations for 32-, 64-, and 128-bit payloads.
Examples
using dec32_t = math::decimal_t<std::uint32_t>;
dec32_t a{"123.45"}; // string → BID
dec32_t b{12345u, -2}; // coefficient/exponent → BID
dec32_t c = dec32_t::from(1.25); // binary float → BID
auto raw_bid = static_cast<math::bid_t<std::uint32_t>>(a).value;
auto raw_dpd = static_cast<math::dpd_t<std::uint32_t>>(a).value;
dec32_t d{ math::dpd_t<std::uint32_t>{raw_dpd} }; // DPD → BID → decimal
auto s = static_cast<std::string>(d); // BID → text
auto x = static_cast<double>(d); // BID → binary float
using dec64_t = math::decimal_t<std::uint64_t>;
dec64_t a{"123.45"}; // string → BID
dec64_t b{12345ull, -2}; // coefficient/exponent → BID
dec64_t c = dec64_t::from(1.25); // binary float → BID
auto raw_bid = static_cast<math::bid_t<std::uint64_t>>(a).value;
auto raw_dpd = static_cast<math::dpd_t<std::uint64_t>>(a).value;
dec64_t d{ math::dpd_t<std::uint64_t>{raw_dpd} }; // DPD → BID → decimal
auto s = static_cast<std::string>(d); // BID → text
auto x = static_cast<double>(d); // BID → binary float
using dec128_t = math::decimal_t<BID_UINT128>;
dec128_t a{"123.45"}; // string → BID
dec128_t b{BID_UINT128{12345u}, -2}; // coefficient/exponent → BID
dec128_t c = dec128_t::from(1.25); // binary float → BID
auto raw_bid = static_cast<math::bid_t<BID_UINT128>>(a).value;
auto raw_dpd = static_cast<math::dpd_t<BID_UINT128>>(a).value;
dec128_t d{ math::dpd_t<BID_UINT128>{raw_dpd} }; // DPD → BID → decimal
auto s = static_cast<std::string>(d); // BID → text
auto x = static_cast<double>(d); // BID → binary float
Decomposition follows: \(x = (-1)^s \cdot C \cdot 10^e\)
Explicit classification of special values.
| Source | Target | Status | Notes |
|---|---|---|---|
(significand, exponent) |
decimal | supported | Encoded as BID using uint32_to_bid32() |
const char*, std::string, std::string_view |
decimal | supported | Parsed via Intel BID string conversion |
float, double, long double |
decimal | supported | Converted to BID |
| decimal | std::string |
supported | Printed from BID |
| decimal | float / double / long double |
supported | Converted from BID |
| decimal | bid_t<std::uint32_t> |
supported | Exposes raw internal BID bits |
| decimal | dpd_t<std::uint32_t> |
supported | Exports DPD from internal BID |
dpd_t<std::uint32_t> |
decimal | supported | Imports DPD via BID |
| Source | Target | Status | Notes |
|---|---|---|---|
(significand, exponent) |
decimal | supported | Encoded as BID using uint64_to_bid64() |
const char*, std::string, std::string_view |
decimal | supported | Parsed via Intel BID string conversion |
float, double, long double |
decimal | supported | Converted to BID |
| decimal | std::string |
supported | Printed from BID |
| decimal | float / double / long double |
supported | Converted from BID |
| decimal | bid_t<std::uint64_t> |
supported | Exposes raw internal BID bits |
| decimal | dpd_t<std::uint64_t> |
supported | Exports DPD from internal BID |
dpd_t<std::uint64_t> |
decimal | supported | Imports DPD via BID |
| Source | Target | Status | Notes |
|---|---|---|---|
(significand, exponent) |
decimal | supported | Encoded as BID using uint128_to_bid128() |
const char*, std::string, std::string_view |
decimal | supported | Parsed via Intel BID string conversion |
float, double, long double |
decimal | supported | Converted to BID |
| decimal | std::string |
supported | Printed from BID |
| decimal | float / double / long double |
supported | Converted from BID |
| decimal | bid_t<BID_UINT128> |
supported | Exposes raw internal BID bits |
| decimal | dpd_t<BID_UINT128> |
supported | Exports DPD from internal BID |
dpd_t<BID_UINT128> |
decimal | supported | Imports DPD via BID |
The conversion paths are exercised directly by the test suite across all supported formats. For decimal32 and decimal64, this includes string construction, floating-point construction, explicit floating conversion, and full DPD roundtrip validation. decimal128 is covered with the same guarantees, including string and floating-point construction as well as DPD roundtrip support, ensuring consistent behavior across all widths. In addition to conversion, the library provides full structural decomposition of BID-encoded values into: \((\text{sign},\ \text{coefficient},\ \text{exponent})\) via: auto [kind, coefficient, exponent] = math::decompose(x);
This interface is implemented uniformly across decimal32, decimal64, and decimal128, and operates over the complete IEEE 754 decimal domain. All value classes are supported, including finite values (both positive and negative), signed zero, infinities (±inf), and NaN.
For finite values, the decomposition follows: \(x = (-1)^s \cdot C \cdot 10^e\) where:
* kind encodes the sign and classification
* coefficient is the integer significand
* exponent is the unbiased decimal exponent