ieee_754/
helper.rs

1#[derive(Debug)]
2pub struct ComputeMantissaBits;
3
4impl ComputeMantissaBits {
5    pub fn round_up(bits: &mut Vec<u8>) -> Result<Vec<u8>, String> {
6        let mut is_overflow: bool = true;
7        let mut i = bits.len() - 1;
8
9        loop {
10            if let Some(b) = bits.get_mut(i) {
11                if *b == 1 {
12                    *b = 0;
13                } else {
14                    *b = 1;
15                    is_overflow = false;
16                    break;
17                }
18            } else {
19                return Err("unable to round up, no bit to compare".to_string());
20            }
21            if i == 0 {
22                break;
23            }
24            i -= 1;
25        }
26        if is_overflow {
27            return Err("unable to round up, overflow".to_string());
28        }
29        Ok(bits.to_owned())
30    }
31
32    pub fn compute(input: Vec<u8>, length: usize) -> Result<Vec<u8>, String> {
33        let mut bits = input.get(0..length).unwrap().to_vec();
34        let guard_bit: u8 = *input.get(length).unwrap_or(&0);
35        let round_bit: u8 = *input.get(length + 1).unwrap_or(&0);
36        let sticky_bits: Vec<u8> = input.get(length + 2..).unwrap_or(&Vec::new()).to_vec();
37        let mut is_round_up = false;
38        if guard_bit == 1 {
39            if round_bit == 1 {
40                is_round_up = true;
41            } else if round_bit == 0 {
42                if sticky_bits
43                    .clone()
44                    .into_iter()
45                    .filter(|v| *v == 1)
46                    .collect::<Vec<u8>>()
47                    .len()
48                    > 0
49                {
50                    is_round_up = true;
51                } else {
52                    if let Some(last_bit) = bits.last() {
53                        if *last_bit == 1 {
54                            is_round_up = true;
55                        }
56                    }
57                }
58            }
59        }
60        if is_round_up {
61            bits = Self::round_up(&mut bits)?;
62        }
63        Ok(bits)
64    }
65}
66
67#[derive(Debug, Clone)]
68pub struct SplitFloat;
69impl SplitFloat {
70    pub fn f32(input: f32) -> Result<(u8, u32, f32), String> {
71        let sign: u8 = if input.is_sign_negative() { 1 } else { 0 };
72        let value: String = input.to_string().replace("-", "");
73        let vsplitted: Vec<&str> = if !value.contains(".") {
74            vec![&"0", &"0"]
75        } else {
76            value.split(".").collect()
77        };
78        let integer_part: u32 = if let Some(v) = vsplitted.get(0) {
79            match v.parse::<u32>() {
80                Ok(v) => v,
81                Err(error) => return Err(error.to_string()),
82            }
83        } else {
84            return Err("invalid floating integer part value".to_string());
85        };
86        let fractional_part: f32 = if let Some(v) = vsplitted.get(1) {
87            match format!("0.{}", v).parse::<f32>() {
88                Ok(v) => v,
89                Err(error) => return Err(error.to_string()),
90            }
91        } else {
92            return Err("invalid floating fractional part value".to_string());
93        };
94        Ok((sign, integer_part, fractional_part))
95    }
96    pub fn f64(input: f64) -> Result<(u8, u64, f64), String> {
97        let sign: u8 = if input.is_sign_negative() { 1 } else { 0 };
98        let value: String = input.to_string().replace("-", "");
99        let vsplitted: Vec<&str> = if !value.contains(".") {
100            vec![&"0", &"0"]
101        } else {
102            value.split(".").collect()
103        };
104        let integer_part: u64 = if let Some(v) = vsplitted.get(0) {
105            match v.parse::<u64>() {
106                Ok(v) => v,
107                Err(error) => return Err(error.to_string()),
108            }
109        } else {
110            return Err("invalid floating integer part value".to_string());
111        };
112        let fractional_part: f64 = if let Some(v) = vsplitted.get(1) {
113            match format!("0.{}", v).parse::<f64>() {
114                Ok(v) => v,
115                Err(error) => return Err(error.to_string()),
116            }
117        } else {
118            return Err("invalid floating fractional part value".to_string());
119        };
120        Ok((sign, integer_part, fractional_part))
121    }
122}