hexfloat2/
format.rs

1use std::fmt::Display;
2use std::num::FpCategory;
3
4use crate::float::FloatBits;
5use crate::HexFloat;
6
7// FIXME: we should also impl the UpperHex and LowerHex traits.
8
9impl<F> Display for HexFloat<F>
10where
11    F: FloatBits + Display,
12{
13    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14        match self.category() {
15            FpCategory::Nan | FpCategory::Infinite => {
16                return self.0.fmt(f);
17            }
18            _ => {}
19        };
20        let (sign, exponent, mantissa) = self.to_parts();
21
22        let bias = F::EXPONENT_BIAS as i32;
23        // The mantissa MSB needs to be shifted up to the nearest nibble.
24        let mshift = (4 - (F::MANTISSA_BITS as u32) % 4) % 4;
25        let mantissa = mantissa << mshift;
26        // The width is rounded up to the nearest char (4 bits)
27        let mwidth = (F::MANTISSA_BITS as usize + 3) / 4;
28        let sign_char = if sign { "-" } else { "" };
29        let mut exponent: i32 = exponent.into() - bias;
30        let leading = if exponent == -bias {
31            // subnormal number means we shift our output by 1 bit.
32            exponent += 1;
33            "0."
34        } else {
35            "1."
36        };
37
38        write!(f, "{sign_char}0x{leading}{mantissa:0mwidth$x}p{exponent}")
39    }
40}