Expand description
IEEE 754 half-precision floats, as used for Traction speeds.
Traction speeds are in scale meters/second. The sign bit carries the
direction (set = reverse), so -0.0 means “stopped, facing reverse”.
The Traction Control Standard sends speeds as a 16-bit IEEE 754 “binary16” value: 1 sign bit, 5 exponent bits (bias 15) and 10 mantissa bits, big-endian on the wire. That gives roughly three significant decimal digits, which is plenty for a model train: 126 scale mph (56.3 m/s) round-trips to within 0.1%.
15 14 10 9 0
+---+-------+------------+
| S | exp | mantissa | S = 1 → reverse, S = 0 → forward
+---+-------+------------+Because direction lives in the sign bit, 0x0000 (+0.0) and 0x8000
(-0.0) are both “stopped” but remember different directions. Rust’s
f32 preserves the sign of zero, so the conversions here do too. Most
code should use traction::Speed, which wraps
these functions with direction-aware helpers.
This module is a small, dependency-free converter that works in
no_std. It rounds to nearest-even, produces subnormals for tiny
values, saturates to infinity on overflow and preserves NaN.
use rolcb::float16::{from_f32, to_f32};
assert_eq!(from_f32(1.0), 0x3C00);
assert_eq!(from_f32(-2.0), 0xC000);
assert_eq!(from_f32(-0.0), 0x8000); // stopped, reverse
assert_eq!(to_f32(0x3800), 0.5);
assert!(to_f32(0x8000).is_sign_negative());
assert_eq!(from_f32(1.0e6), 0x7C00); // too big: +infinity