summaryrefslogblamecommitdiff
path: root/meap/ch5/src/main.rs
blob: 2fcf60c36d7a2d25b3e871bedc1d1cb58253499e (plain) (tree)






























































































































































































                                                                                          
////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);
    }
}