Skip to main content

Module float16

Module float16 

Source
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

Functions§

from_f32
Convert an f32 to IEEE half-float bits (round-to-nearest-even).
to_f32
Convert IEEE half-float bits to f32.