ddn.encoding.bid

ddn.encoding.bid — IEEE 754 binary integer decimal (BID) interchange for decimal64 and decimal128.

Field/bit and buffer codecs for the BID encoding only — **no IEEE arithmetic**, no ddn.num.decimal, no var, no binary-float bridge (design record doc/DDN-ENCODING.md D30–D36). Buffers are big-endian (interchange convention).

Semantics summary:

  • Classification and field extraction are total: every bit

    pattern classifies (classify64/128), and fromBits64/128 preserve raw fields — including NaN payloads, signed zeros, infinity trailing bits and non-canonical finites (flagged).

  • Field→bits and buffer operations are fallible Result

    operations: canonical writes reject out-of-range fields (INVALID_FIELD), short output is non-committing (INSUFFICIENT_CAPACITY), short input is TRUNCATED.

  • Value interpretation of non-canonical finites (coefficient

    beyond 10^p−1) is the standard's "treat as zero" rule — this codec flags instead of erasing, and documents the rule.

decimal64 layout: sign (bit 63); 5-bit combination (bits 62..58): 11110 infinity, 11111 NaN (bit 57: 0 quiet / 1 signaling, bits 56..0 payload); otherwise finite — small form when bits 62..61 ≠ 11: E′ = bits 62..53 (10 bits, bias 398), C = bits 52..0; large form when 11: E′ top two = bits 60..59, low eight = bits 58..51, C = implicit 100 before bits 50..0. Value = (−1)^s × 10^(E′−398) × C; canonical: C ≤ 10^16 − 1 (which also bounds E′ ≤ 767 by construction).

Example:

import ddn.encoding.bid;

auto v = bid.fromBits64(0x31C0000000000001uL); // decimal64 1.0
assert(v.cls == BidClass.FINITE && !v.sign);
assert(v.biasedExponent == 398 && v.coefficient == 1);

Types 4

Bit-pattern classification (total).

FINITEA finite value (canonical or not — see `nonCanonical`).
INFINITY±Infinity.
NAN_QUIETQuiet NaN (payload preserved).
NAN_SIGNALINGSignaling NaN (payload preserved).
structBidError

Recoverable BID failure with bounded context: context names the offending field for INVALID_FIELD (0 coefficient, 1 biased exponent, 2 payload/trailing); it is 0 for the retryable classes.

Fields
Code codeWhich failure happened.
size_t contextOffending field index or 0.
Nested Templates
CodeFailure classification.
structBid64

Extracted decimal64 fields (raw-preserving).

nanPayload holds bits 56..0 for NaNs; infTrailing the 58 meaning-free bits after an infinity combination (normally zero); nonCanonical flags finite coefficients beyond 10^16 − 1 (the standard's input rule interprets those as zero — flagged, never erased, here).

Fields
bool signSign bit (meaningful for finites and infinities; ignored for NaNs).
BidClass clsBit-pattern class.
ushort biasedExponentBiased exponent (10 bits; finites only).
ulong coefficientCoefficient as a binary integer (finites only, as extracted).
ulong nanPayloadNaN payload bits 56..0 (57 bits).
ulong infTrailingInfinity trailing bits 57..0 (58 bits, no defined meaning).
bool nonCanonicalFinite coefficient beyond 10^16 − 1 (value: treat-as-zero rule).
structBid128

Extracted decimal128 fields (raw-preserving, like Bid64).

Fields
bool signSign bit (finites and infinities; ignored for NaNs).
BidClass clsBit-pattern class.
ushort biasedExponentBiased exponent (14 bits; finites only).
Int128 coefficientCoefficient as a binary integer (finites only, as extracted).
Int128 nanPayloadNaN payload bits 121..0 (122 bits).
Int128 infTrailingInfinity trailing bits 122..0 (123 bits, no defined meaning).
bool nonCanonicalFinite coefficient beyond 10^34 − 1 (treat-as-zero value rule).

Functions 10

fnBidClass classify64(ulong bits) @safe pure nothrow @nogcClassifies a raw decimal64 bit pattern.
fnBid64 fromBits64(ulong bits) @safe pure nothrow @nogcExtracts decimal64 fields from raw bits (total, raw-preserving).
fnResult!(ulong, BidError) bitsOf64(const Bid64 v) @safe nothrow @nogcBuilds the decimal64 bit pattern from canonical fields.
fnResult!(size_t, BidError) encode64(const Bid64 v, return scope ubyte[] dst) @safe nothrow @nogcWrites a decimal64 value as 8 big-endian bytes (non-committing).
fnResult!(Bid64, BidError) decode64(scope const(ubyte)[] src) @safe pure nothrow @nogcReads a decimal64 value from 8 big-endian bytes.
fnBidClass classify128(Int128 bits) @safe pure nothrow @nogcDitto (decimal128).
fnBid128 fromBits128(Int128 bits) @safe pure nothrow @nogcDitto (decimal128).
fnResult!(Int128, BidError) bitsOf128(const Bid128 v) @safe nothrow @nogcDitto (decimal128). Canonical writes use the single 113-bit form.
fnResult!(size_t, BidError) encode128(const Bid128 v, return scope ubyte[] dst) @safe nothrow @nogcDitto (decimal128, 16 big-endian bytes).
fnResult!(Bid128, BidError) decode128(scope const(ubyte)[] src) @safe pure nothrow @nogcDitto (decimal128, 16 big-endian bytes).

Variables 7

enumvarbid64Bias = 398

decimal64 exponent bias.

enumvarbid64MaxBiasedExponent = 767

Largest canonical biased exponent (adjusted Emax 384 ⇒ E′ 767).

enumvarbid64MaxCoefficient = 9_999_999_999_999_999uL

Largest canonical coefficient (p = 16 digits).

enumvarbid128Bias = 6176

decimal128 exponent bias.

enumvarbid128MaxBiasedExponent = 12287

Largest canonical biased exponent (adjusted Emax 6144 ⇒ E′ 12287).

enumvarbid128MaxCoefficient = Int128(99_999_999_999_999_999uL) * Int128(100_000_000_000_000_001uL)

Largest canonical coefficient (p = 34 digits; < 2^113, so the large significand form is never canonical in this width).

enumvarbid128CoefficientBits = 113

Bits in the decimal128 coefficient field.