From 7e8ee5ed9cad6484e9f13f81731b102ced58402e Mon Sep 17 00:00:00 2001 From: Adam Carpenter Date: Tue, 9 Jul 2019 15:14:04 -0400 Subject: Init. --- meap/ch5/src/main.rs | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100755 meap/ch5/src/main.rs (limited to 'meap/ch5/src') diff --git a/meap/ch5/src/main.rs b/meap/ch5/src/main.rs new file mode 100755 index 0000000..2fcf60c --- /dev/null +++ b/meap/ch5/src/main.rs @@ -0,0 +1,191 @@ +////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); + } +} -- cgit v1.2.3