////use std::mem; //const BIAS: i32 = 127; //const RADIX: f32 = 2.0; // //fn main() { //let a: u16 = 0b1100_0011_1100_0011; //dbg!(a); ////let b: i16 = 0b1100_0011_1100_0011; ////dbg!(b); // let a: f32 = 42.42; // let frankentype: u32 = unsafe { // std::mem::transmute(a) // }; // // //println!("{:032b}", frankentype); // let mut i: u16 = 0; // // loop { // print!("{}\t", i); // if i % 10000 == 0 { // print!("\n"); // } // i += 1000; // } //let zero: u16 = 0b0000_0000_0000_0000; //let one: u16 = 0b0000_0000_0000_0001; //let two: u16 = 0b0000_0000_0000_0010; //let big_533: u16 = 0b1111_1111_1111_1101; //let big_534: u16 = 0b1111_1111_1111_1110; //let big_535: u16 = 0b1111_1111_1111_1111; //prinlt!("{}, {}, {}, ..., {}, {}, {}\n", zero, one, two, big_533, big_534, big_535); //let big_533: u16 = 0b1111_1111_1111_1101; // let (a, b) = (200, 200); // let c: u8 = a + b; // println!("200 + 200 = {}", c); // let big_endian: [u8; 4] = [ // 0xAA, // 0xBB, // 0xCC, // 0xDD, // ]; // // let little_endian: [u8; 4] = [ // 0xDD, // 0xCC, // 0xBB, // 0xAA, // ]; // // let (a, b): (i32, i32) = unsafe { // (mem::transmute(big_endian), mem::transmute(little_endian)) // }; // // dbg!(a); // dbg!(b); // let n: f32 = 42.42; // // let (signbit, exponent, fraction) = deconstruct_f32(n); // let (sign, exponent, mantissa) = decode_f32_parts(signbit, exponent, fraction); // let reconstituted_n = f32_from_parts(sign, exponent, mantissa); // dbg!(n); // dbg!(signbit); // dbg!(exponent); // dbg!(mantissa); // dbg!(reconstituted_n); //} // //fn deconstruct_f32(n: f32) -> (u32, u32, u32) { // let n_: u32 = unsafe { std::mem::transmute(n) }; // // let sign = (n_ >> 31) & 1; // let exponent = (n_ >> 23) & 0xff; // let fraction = 0b00000000_01111111_11111111_11111111 & n_; // (sign, exponent, fraction) //} // //fn decode_f32_parts(sign: u32, exponent: u32, fraction: u32) -> (f32, f32, f32) { // let signed_1 = (-1.0_f32).powf(sign as f32); // // let exponent = (exponent as i32) - BIAS; // let exponent = RADIX.powf(exponent as f32); // // let mut mantissa: f32 = 1.0; // // for i in 0..23_u32 { // let one_at_bit_i = 1 << i; // // if (one_at_bit_i & fraction) != 0 { // mantissa += 2_f32.powf((i as f32) - 23.0); // } // } // // (signed_1, exponent, mantissa) //} // //fn f32_from_parts(sign: f32, exponent: f32, mantissa: f32) -> f32 { // sign * exponent * mantissa //} fn mock_rand(n: u8) -> f32 { let base: u32 = 0b0_01111110_00000000000000000000000; let large_n = (n as u32) << 15; let f32_bits = base | large_n; let m = f32::from_bits(f32_bits); 2.0 * (m - 0.5) } fn main() { dbg!(mock_rand(0xff)); dbg!(mock_rand(0x77)); dbg!(mock_rand(0x00)); } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Q7(i8); impl From for Q7 { fn from(n: f64) -> Self { if n >= 1.0 { Q7(127) } else if n <= -1.0 { Q7(-128) } else { Q7((n * 128.0) as i8) } } } impl From for f64 { fn from(n: Q7) -> f64 { (n.0 as f64) * 2f64.powf(-7.0) } } impl From for Q7 { fn from(n: f32) -> Self { Q7::from(n as f64) } } impl From for f32 { fn from(n: Q7) -> f32 { f64::from(n) as f32 } } #[cfg(test)] mod tests { use super::*; #[test] fn out_of_bounds() { assert_eq!(Q7::from(10.), Q7::from(1.)); assert_eq!(Q7::from(-10.), Q7::from(-1.)); } #[test] fn f32_to_q7() { let n1: f32 = 0.7; let q1 = Q7::from(n1); let n2: f32 = -0.4; let q2 = Q7::from(n2); let n3: f32 = 123.0; let q3 = Q7::from(n3); assert_eq!(q1, Q7(89)); assert_eq!(q2, Q7(-51)); assert_eq!(q3, Q7(127)); } #[test] fn q7_to_f32() { let q1 = Q7::from(0.7); let n1 = f32::from(q1); assert_eq!(n1, 0.6953125); let q2 = Q7::from(n1); let n2 = f32::from(q2); assert_eq!(n1, n2); } }