pub fn decode_packed_decimal(
data: &[u8],
digits: u16,
scale: i16,
signed: bool,
) -> Result<SmallDecimal>Expand description
Decode packed decimal (COMP-3) field with comprehensive error context
Decodes COMP-3 packed decimal format where each byte contains two decimal digits (nibbles), with the last nibble containing the sign. This function uses optimized fast paths for common enterprise data patterns.
§Arguments
data- Raw byte data containing the packed decimaldigits- Number of decimal digits in the field (1-18 supported)scale- Number of decimal places (can be negative for scaling)signed- Whether the field is signed (true) or unsigned (false)
§Returns
A SmallDecimal containing the decoded value
§Errors
Returns an error if the packed decimal data contains invalid nibbles.
All errors include proper context information (record_index, field_path, byte_offset).
§Performance
This function uses specialized fast paths for common cases:
- 1-5 byte fields: Direct decoding with minimal validation
- Empty data: Immediate zero return
- Digits > 18: Error (maximum supported precision)
§Examples
§Basic Positive Value
use copybook_codec::numeric::{decode_packed_decimal};
// "123" as COMP-3: [0x12, 0x3C] (12 positive, 3C = positive sign)
let data = [0x12, 0x3C];
let result = decode_packed_decimal(&data, 3, 0, true)?;
assert_eq!(result.to_string(), "123");§Negative Value
use copybook_codec::numeric::{decode_packed_decimal};
// "-456" as COMP-3: [0x04, 0x56, 0xD] (456 negative)
let data = [0x04, 0x56, 0xD];
let result = decode_packed_decimal(&data, 3, 0, true)?;
assert_eq!(result.to_string(), "-456");§Decimal Scale
use copybook_codec::numeric::{decode_packed_decimal};
// "12.34" with 2 decimal places: [0x12, 0x34, 0xC]
let data = [0x12, 0x34, 0xC];
let result = decode_packed_decimal(&data, 4, 2, true)?;
assert_eq!(result.to_string(), "12.34");§Unsigned Field
use copybook_codec::numeric::{decode_packed_decimal};
// Unsigned "789": [0x07, 0x89, 0xF] (F = unsigned sign)
let data = [0x07, 0x89, 0xF];
let result = decode_packed_decimal(&data, 3, 0, false)?;
assert_eq!(result.to_string(), "789");§Zero Value
use copybook_codec::numeric::{decode_packed_decimal};
// Zero: [0x00, 0x0C]
let data = [0x00, 0x0C];
let result = decode_packed_decimal(&data, 2, 0, true)?;
assert_eq!(result.to_string(), "0");§See Also
encode_packed_decimal- For encoding packed decimalsdecode_packed_decimal_with_scratch- For zero-allocation decodingdecode_packed_decimal_to_string_with_scratch- For direct string output