Module number

Source
Expand description

Implementation of the number schema

When binary data is exchanged a common objective is to reduce the data size. For this the IEEE 754 formats are not suited. To reduce the size of a floating-point number linear interpolation can be used to fit a number into a smaller integer.

§Parameters

KeyTypeDefaultComment
"byteorder"string“bigendian”The order in which the bytes are encoded.
"length"uint4Number of bytes of the encoded number
"signed"booltrueWhether the number is signed or not
"bits"uintoptionalNumber of bits the bitfield covers
"bitoffset"uintoptionalNumber of bits the bitfield is shifted
"scale"doubleoptionalFactor to scale the encoded value
"offset"doubleoptionalOffset for the encoded value

§Validation

If none of the optional parameters are provided only a length of 4 or 8 byte are valid (single and double precision floating-point numbers, IEEE 754). However, there are methods to encode floating-point numbers as integers.

§Features

§Linear Interpolation

Linear interpolation is performed if "bits", "bitoffset", "scale" or "offset" are set. If "scale" is not set the default value 1.0 is assumed. If "offset" is not set the default value 0.0 is assumed.

For linear interpolation the parameters "scale" and "offset" are used. The formulae are as follows:

  • Encoding: encoded_value = (json_value - offset) / scale
  • Decoding: json_value = scale * encoded_value + offset

An interpolated value is encoded with the integer schema defined by the number schema. Accordingly, it is also possible to encode an interpolated value in a bitfield.

§Example

The schema describes that a floating-point JSON value is encoded in the lower 11 bits (max 2047) with a scale of 0.001 and an offset of 1.6. The calculation to encode 3.0:

(3.0 - 1.6) / 0.001 = 1400 = 0b0000_0101_0111_1000 = encoded_value
let schema = json!({
    "type": "number",
    "offset": 1.6,
    "scale": 0.001,
    "length": 2,
    "bits": 11
});

let mut scope = json_schema::Scope::new();
let j_schema = scope.compile_and_return(schema.clone(), false)?;
let schema = from_value::<DataSchema>(schema)?;

let value = json!(3.0);
assert!(j_schema.validate(&value).is_valid());
let mut encoded = Vec::new();
schema.encode(&mut encoded, &value)?;
let expected = [ 0b0000_0101, 0b0111_1000 ];
assert_eq!(&expected, encoded.as_slice());

let mut encoded = std::io::Cursor::new(encoded);
let back = schema.decode(&mut encoded)?;
assert!(j_schema.validate(&back).is_valid());
// This would fail due to rounding errors
// assert_eq!(back, value);

Enums§

DecodingError
Errors decoding a string with a NumberSchema.
EncodingError
Errors encoding a string with a NumberSchema.
NumberSchema
The number schema describes a numeric value (further information on the module’s documentation).
ValidationError
Errors validating a NumberSchema.