Message

Decimal

Exact decimal number, mirroring Rust's rust_decimal::Decimal: a 96-bit unsigned integer mantissa, a base-10 scale and a sign.

value = (hi << 64 | lo) / 10^scale, negated when `negative` is true

Example: lo=12345, hi=0, scale=2, negative=false represents 123.45. Decoding in Rust (with the rust_decimal crate):

let lo = (d.lo & 0xFFFF_FFFF) as u32;
let mid = (d.lo >> 32) as u32;
let value = Decimal::from_parts(lo, mid, d.hi, d.negative, d.scale);

Decoding in Python (E-notation string: exact regardless of the decimal context's precision, and faster than dividing by 10^scale):

from decimal import Decimal
mantissa = (d.hi << 64) | d.lo
value = Decimal(f"{'-' if d.negative else ''}{mantissa}E-{d.scale}")
Proto definition.proto
message Decimal {
  uint64 lo = 1;
  uint32 hi = 2;
  uint32 scale = 3;
  bool negative = 4;
}
Fields
lo uint64 1
Low 64 bits of the 96-bit mantissa.
hi uint32 2
High 32 bits of the 96-bit mantissa.
scale uint32 3
Number of decimal digits after the point, i.e. the power of ten the mantissa is divided by. At most 28.
negative bool 4
True when the value is negative.