1pub mod helper;
2pub mod ieee754;
3
4use crate::ieee754::{IEEE754_32bit, IEEE754_64bit, ValidationError};
5
6#[derive(Debug)]
7pub struct IEEE754;
8
9impl IEEE754 {
10 pub fn to_hex(binary: Vec<u8>) -> Result<String, String> {
11 let mut hex = String::new();
12 for b in binary.chunks(4) {
13 let byte_str: String = b
14 .into_iter()
15 .map(|v| v.to_string())
16 .collect::<Vec<String>>()
17 .concat();
18
19 match u8::from_str_radix(&byte_str, 2) {
20 Ok(v) => {
21 hex.push_str(&format!("{:X}", v));
22 }
23 Err(error) => return Err(error.to_string()),
24 }
25 }
26 Ok(hex)
27 }
28
29 pub fn to_32bit_hex(value: f32) -> Result<String, String> {
30 let binary: Vec<u8> = IEEE754_32bit::get_binary(value)?;
31 let hex: String = IEEE754::to_hex(binary)?;
32 Ok(hex)
33 }
34
35 pub fn to_64bit_hex(value: f64) -> Result<String, String> {
36 let binary: Vec<u8> = IEEE754_64bit::get_binary(value)?;
37 let hex: String = IEEE754::to_hex(binary)?;
38 Ok(hex)
39 }
40
41 pub fn to_binary(values: Vec<u32>) -> Result<Vec<u8>, ValidationError> {
42 let mut binaries: Vec<u8> = Vec::new();
43 if values.is_empty() {
44 return Err(ValidationError::EmptyValues);
45 }
46 for v in values.iter() {
47 for x in &mut format!("{:08b}", v).chars() {
48 match u8::from_str_radix(&x.to_string(), 2) {
49 Ok(value) => binaries.push(value),
50 Err(_) => return Err(ValidationError::ParseError),
51 }
52 }
53 }
54 Ok(binaries)
55 }
56
57 fn get_sign_bit(binaries: &[u8]) -> Result<i8, ValidationError> {
58 if binaries.is_empty() {
59 return Err(ValidationError::EmptySignBit);
60 }
61 match binaries.first() {
62 Some(value) => Ok(if value == &0 { 1 } else { -1 }),
63 None => Err(ValidationError::InvalidSignBit),
64 }
65 }
66
67 pub fn to_64bit_float(values: Vec<u32>) -> Result<f64, ValidationError> {
68 let binaries: Vec<u8> = Self::to_binary(values)?;
69 let sign_bit: i8 = Self::get_sign_bit(&binaries)?;
70
71 match binaries.get(1..12) {
73 Some(exponent_binaries) => {
74 match binaries.get(12..) {
76 Some(mantissa_binaries) => {
77 IEEE754_64bit::validate(exponent_binaries, mantissa_binaries)?;
78 let exponent: i32 = IEEE754_64bit::get_exponent(exponent_binaries)?;
79 let value: f64 = IEEE754_64bit::get_mantissa(mantissa_binaries, exponent)?;
80 match sign_bit {
81 1 => Ok(value),
82 -1 => Ok(-(value)),
83 _ => Err(ValidationError::InvalidSignBit),
84 }
85 }
86 None => Err(ValidationError::InvalidMantissa),
87 }
88 }
89 None => Err(ValidationError::InvalidExponent),
90 }
91 }
92 pub fn to_32bit_float(values: Vec<u32>) -> Result<f32, ValidationError> {
93 let binaries: Vec<u8> = Self::to_binary(values)?;
94 let sign_bit: i8 = Self::get_sign_bit(&binaries)?;
95
96 match binaries.get(1..9) {
98 Some(exponent_binaries) => {
99 match binaries.get(9..) {
101 Some(mantissa_binaries) => {
102 IEEE754_32bit::validate(exponent_binaries, mantissa_binaries)?;
103 let exponent: i32 = IEEE754_32bit::get_exponent(exponent_binaries)?;
104 let value: f32 = IEEE754_32bit::get_mantissa(mantissa_binaries, exponent)?;
105 match sign_bit {
106 1 => Ok(value),
107 -1 => Ok(-(value)),
108 _ => Err(ValidationError::InvalidSignBit),
109 }
110 }
111
112 None => Err(ValidationError::InvalidMantissa),
113 }
114 }
115 None => Err(ValidationError::InvalidExponent),
116 }
117 }
118}
119#[cfg(test)]
120mod tests {
121 use super::*;
122 use crate::helper::ComputeMantissaBits;
123 use std::f64;
124
125 #[test]
126 fn test_compute_mantissa_bits_computation() {
127 assert_eq!(
128 ComputeMantissaBits::compute(
129 "10101010101010101010101 0 0"
130 .chars()
131 .filter(|&c| c != ' ')
132 .map(|c| c.to_digit(10).unwrap() as u8)
133 .collect::<Vec<u8>>(),
134 23
135 )
136 .unwrap(),
137 "10101010101010101010101"
138 .chars()
139 .map(|c| c.to_digit(10).unwrap() as u8)
140 .collect::<Vec<u8>>()
141 );
142 assert_eq!(
143 ComputeMantissaBits::compute(
144 "10101010101010101010101 1 0"
145 .chars()
146 .filter(|&c| c != ' ')
147 .map(|c| c.to_digit(10).unwrap() as u8)
148 .collect::<Vec<u8>>(),
149 23
150 )
151 .unwrap(),
152 "10101010101010101010110"
153 .chars()
154 .map(|c| c.to_digit(10).unwrap() as u8)
155 .collect::<Vec<u8>>()
156 );
157
158 assert!(ComputeMantissaBits::compute(
159 "11111111111111111111111 1 0"
160 .chars()
161 .filter(|&c| c != ' ')
162 .map(|c| c.to_digit(10).unwrap() as u8)
163 .collect::<Vec<u8>>(),
164 23
165 )
166 .is_err());
167
168 assert_eq!(
169 ComputeMantissaBits::compute(
170 "00000000000000000000000 1 0"
171 .chars()
172 .filter(|&c| c != ' ')
173 .map(|c| c.to_digit(10).unwrap() as u8)
174 .collect::<Vec<u8>>(),
175 23
176 )
177 .unwrap(),
178 "00000000000000000000000"
179 .chars()
180 .map(|c| c.to_digit(10).unwrap() as u8)
181 .collect::<Vec<u8>>(),
182 );
183
184 assert_eq!(
185 ComputeMantissaBits::compute(
186 "01111111111111111111111 1"
187 .chars()
188 .filter(|&c| c != ' ')
189 .map(|c| c.to_digit(10).unwrap() as u8)
190 .collect::<Vec<u8>>(),
191 23
192 )
193 .unwrap(),
194 "10000000000000000000000"
195 .chars()
196 .map(|c| c.to_digit(10).unwrap() as u8)
197 .collect::<Vec<u8>>(),
198 );
199
200 assert!(ComputeMantissaBits::compute(
201 "11111111111111111111111 1"
202 .chars()
203 .filter(|&c| c != ' ')
204 .map(|c| c.to_digit(10).unwrap() as u8)
205 .collect::<Vec<u8>>(),
206 23
207 )
208 .is_err());
209 }
210
211 #[test]
212 fn test_32bit() {
213 let values = vec![0x00, 0x00, 0x00, 0x00];
215 let output = IEEE754::to_32bit_float(values.clone());
216 println!("Input: {:x?}", values);
217 println!("Expected Output: {}", 0.0);
218 assert_eq!(0.0, output.unwrap());
219
220 let values = vec![0x80, 0x00, 0x00, 0x00];
222 let output = IEEE754::to_32bit_float(values.clone());
223 println!("Input: {:x?}", values);
224 println!("Expected Output: {}", -0.0);
225 assert_eq!(-0.0, output.unwrap());
226
227 let values = vec![0xc0, 0x2d, 0xf8, 0x54];
229 let output = IEEE754::to_32bit_float(values.clone());
230 println!("Input: {:x?}", values);
231 println!("Expected Output: {}", -2.7182817);
232 assert_eq!(-2.7182817, output.unwrap());
233
234 let values = vec![0x7f, 0x80, 0x00, 0x00];
236 let output = IEEE754::to_32bit_float(values.clone());
237 println!("Input: {:x?}", values);
238 println!("Expected Output: Error(Infinity)");
239 assert!(output.is_err());
240
241 let values = vec![0xff, 0x80, 0x00, 0x00];
243 let output = IEEE754::to_32bit_float(values.clone());
244 println!("Input: {:x?}", values);
245 println!("Expected Output: Error(Infinity)");
246 assert!(output.is_err());
247
248 let values = vec![0x7f, 0xc0, 0x00, 0x00];
250 let output = IEEE754::to_32bit_float(values.clone());
251 println!("Input: {:x?}", values);
252 println!("Expected Output: Error(NaN)");
253 assert!(output.is_err());
254 }
255
256 #[test]
257 fn test_64bit_to_hex() {
258 let values = 10.001;
259 let output = IEEE754::to_64bit_hex(values.clone());
260 println!("Input: {:x?}", values);
261 println!("Expected Output: 40240083126E978D");
262 assert_eq!(output.unwrap(), "40240083126E978D");
263
264 let values = -85.125;
265 let output = IEEE754::to_64bit_hex(values.clone());
266 println!("Input: {:x?}", values);
267 println!("Expected Output: C055480000000000");
268 assert_eq!(output.unwrap(), "C055480000000000");
269
270 let values = 0.0;
271 let output = IEEE754::to_64bit_hex(values.clone());
272 println!("Input: {:x?}", values);
273 println!("Expected Output: 0000000000000000");
274 assert_eq!(output.unwrap(), "0000000000000000");
275
276 let values = -33.33333333;
277 let output = IEEE754::to_64bit_hex(values.clone());
278 println!("Input: {:x?}", values);
279 println!("Expected Output: C040AAAAAAA38226");
280 assert_eq!(output.unwrap(), "C040AAAAAAA38226");
281
282 let values = -333.33333333;
283 let output = IEEE754::to_64bit_hex(values.clone());
284 println!("Input: {:x?}", values);
285 println!("Expected Output: C074D55555547045");
286 assert_eq!(output.unwrap(), "C074D55555547045");
287
288 let values = 333.33333333;
289 let output = IEEE754::to_64bit_hex(values.clone());
290 println!("Input: {:x?}", values);
291 println!("Expected Output: 4074D55555547045");
292 assert_eq!(output.unwrap(), "4074D55555547045");
293 }
294
295 #[test]
296 fn test_32bit_to_hex() {
297 let values = 10.001;
298 let output = IEEE754::to_32bit_hex(values.clone());
299 println!("Input: {:x?}", values);
300 println!("Expected Output: 41200419");
301 assert_eq!(output.unwrap(), "41200419");
302
303 let values = -85.125;
304 let output = IEEE754::to_32bit_hex(values.clone());
305 println!("Input: {:x?}", values);
306 println!("Expected Output: C2AA4000");
307 assert_eq!(output.unwrap(), "C2AA4000");
308
309 let values = 0.0;
310 let output = IEEE754::to_32bit_hex(values.clone());
311 println!("Input: {:x?}", values);
312 println!("Expected Output: 00000000");
313 assert_eq!(output.unwrap(), "00000000");
314
315 let values = -33.33333333;
316 let output = IEEE754::to_32bit_hex(values.clone());
317 println!("Input: {:x?}", values);
318 println!("Expected Output: C2055555");
319 assert_eq!(output.unwrap(), "C2055555");
320
321 let values = -333.33333333;
322 let output = IEEE754::to_32bit_hex(values.clone());
323 println!("Input: {:x?}", values);
324 println!("Expected Output: C3A6AAAB");
325 assert_eq!(output.unwrap(), "C3A6AAAB");
326
327 let values = 333.33333333;
328 let output = IEEE754::to_32bit_hex(values.clone());
329 println!("Input: {:x?}", values);
330 println!("Expected Output: 43A6AAAB");
331 assert_eq!(output.unwrap(), "43A6AAAB");
332 }
333
334 #[test]
335 fn test_64bit() {
336 let values = vec![0xc0, 0x52, 0xaf, 0xbe, 0x4, 0x89, 0x76, 0x8e];
338 let output = IEEE754::to_64bit_float(values.clone());
339 println!("Input: {:x?}", values);
340 println!("Expected Output: {}", -74.74597276138431);
341 assert_eq!(-74.74597276138431, output.unwrap());
342
343 let values = vec![0xc0, 0x09, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0];
345 let output = IEEE754::to_64bit_float(values.clone());
346 println!("Input: {:x?}", values);
347 println!("Expected Output: {}", -3.125);
348 assert_eq!(-3.125, output.unwrap());
349
350 let values = vec![0x7f, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0];
352 let output = IEEE754::to_64bit_float(values.clone());
353 println!("Input: {:x?}", values);
354 println!("Expected Output: Error");
355 assert!(output.is_err());
356
357 let values = vec![0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0];
359 let output = IEEE754::to_64bit_float(values.clone());
360 println!("Input: {:x?}", values);
361 println!("Expected Output: Error");
362 assert!(output.is_err());
363
364 let values = vec![0x7f, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0];
367 let output = IEEE754::to_64bit_float(values.clone());
368 println!("Input: {:x?}", values);
369 println!("Expected Output: Error");
370 assert!(output.is_err());
371
372 let values = vec![0x7f, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0];
374 let output = IEEE754::to_64bit_float(values.clone());
375 println!("Input: {:x?}", values);
376 println!("Expected Output: Error");
377 assert!(output.is_err());
378
379 let values = vec![0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0];
381 let output = IEEE754::to_64bit_float(values.clone());
382 println!("Input: {:x?}", values);
383 println!("Expected Output: {}", 0.0);
384 assert_eq!(0.0, output.unwrap());
385
386 let values = vec![0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18];
388 let output = IEEE754::to_64bit_float(values.clone());
389 println!("Input: {:x?}", values);
390 println!("Expected Output: {}", f64::consts::PI);
391 assert_eq!(f64::consts::PI, output.unwrap());
392
393 let values = vec![0x40, 0x05, 0xbf, 0x0a, 0x8b, 0x14, 0x57, 0x69];
395 let output = IEEE754::to_64bit_float(values.clone());
396 println!("Input: {:x?}", values);
397 println!("Expected Output: {}", f64::consts::E);
398 assert_eq!(f64::consts::E, output.unwrap());
399 }
400}