////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<f64> 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<Q7> for f64 {
fn from(n: Q7) -> f64 {
(n.0 as f64) * 2f64.powf(-7.0)
}
}
impl From<f32> for Q7 {
fn from(n: f32) -> Self {
Q7::from(n as f64)
}
}
impl From<Q7> 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);
}
}