decompose_float/
fmt.rs

1use crate::DecomposeResult;
2use std::fmt;
3
4impl fmt::Display for DecomposeResult {
5    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
6        let s = match self {
7            DecomposeResult::Normal { is_neg, exp, mantissa } => format!(
8                "{}{}2^{}",
9                if *is_neg { "-" } else { "" },
10                if *mantissa == 1 << 127 {
11                    String::new()
12                } else {
13                    let mut m = mantissa >> 96;
14                    m &= 0x7fff_ffff;  // 0 ~ 2_147_483_647
15                    m *= 1_000_000_000;
16                    m /= 0x8000_0000;  // 0 ~ 999_999_999
17                    let rem = m % 10;
18                    m /= 10;
19
20                    // TODO: There's a small edge case
21                    // if rem > 4 && m == 99_999_999, it has to add `exp` by 1, but it doesn't
22                    if rem > 4 && m != 99_999_999 {
23                        m += 1;
24                    }
25
26                    let mut m = format!("{m:08}");
27
28                    while m.len() > 0 && m.chars().last().unwrap() == '0' {
29                        m = m.get(..(m.len() - 1)).unwrap().to_string();
30                    }
31
32                    if m.is_empty() {
33                        String::new()
34                    }
35
36                    else {
37                        format!("1.{m}*")
38                    }
39                },
40                if *exp >= 0 { exp.to_string() } else { format!("({exp})") },
41            ),
42            DecomposeResult::Zero => String::from("0"),
43            DecomposeResult::NegZero => String::from("-0"),
44            DecomposeResult::Infinity => String::from("inf"),
45            DecomposeResult::NegInfinity => String::from("-inf"),
46            DecomposeResult::NotANumber => String::from("NaN"),
47        };
48
49        write!(formatter, "{s}")
50    }
51}