#![cfg_attr(debug_assertions, allow(unused_variables, dead_code))]
+use std::cell::RefCell;
+use std::rc::Rc;
+
+type Message = String;
+
#[derive(Debug)]
enum StatusMessage {
Ok,
}
+#[derive(Debug)]
+struct Mailbox {
+ messages: Vec<Message>,
+}
+
#[derive(Debug)]
struct CubeSat {
id: u64,
+ mailbox: Mailbox,
}
-fn check_status(sat_id: CubeSat) -> StatusMessage {
+#[derive(Debug)]
+struct GroundStation {
+ radio_freq: f64 // [MHz].
+}
+
+fn check_status(sat_id: &CubeSat) -> StatusMessage {
StatusMessage::Ok
}
fn main() {
- let sat_a = CubeSat { id: 0 };
- let sat_b = CubeSat { id: 1 };
- let sat_c = CubeSat { id: 2 };
-
- let a_status = check_status(sat_a);
- let b_status = check_status(sat_b);
- let c_status = check_status(sat_c);
- println!("a: {:?}, b: {:?}, c: {:?}", a_status, b_status, c_status);
-
+ let base: Rc<RefCell<GroundStation>> =
+ Rc::new(
+ RefCell::new(
+ GroundStation { radio_freq: 42.1 }
+ )
+ );
- let a_status = check_status(sat_a);
- let b_status = check_status(sat_b);
- let c_status = check_status(sat_c);
- println!("a: {:?}, b: {:?}, c: {:?}", a_status, b_status, c_status);
+ println!("base: {:?}", base);
}
--- /dev/null
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "ch5-data-in-depth"
+version = "0.1.0"
--- /dev/null
+[package]
+name = "ch5-data-in-depth"
+version = "0.1.0"
+edition = "2018"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
--- /dev/null
+
+
+struct CPU {
+ current_operation: u16,
+ registers: [u8; 2],
+}
+
--- /dev/null
+const BIAS: i32 = 127;
+const RADIX: f32 = 2.0;
+
+pub fn print_f32(n: f32) {
+ let (sign, exp, frac) = to_parts(n);
+ let (sign_, exp_, mant) = decode(sign, exp, frac);
+ let n_ = from_parts(sign_, exp_, mant);
+
+ println!("{} -> {}", n, n_);
+ println!("field | as bits | as real number");
+ println!("sign | {:01b} | {}", sign, sign_);
+ println!("exponent | {:08b} | {}", exp, exp_);
+ println!("mantissa | {:023b} | {}", frac, mant);
+}
+
+fn to_parts(n: f32) -> (u32, u32, u32) {
+ let bits = n.to_bits();
+
+ let sign = (bits >> 31) & 1;
+ let exponent = (bits >> 23) & 0xFF;
+ let fraction = bits & 0x7F_FF_FF;
+
+ (sign, exponent, fraction)
+}
+
+fn decode(sign: u32, exponent: u32, fraction: u32) -> (f32, f32, f32) {
+ let signed_1 = (-1.0f32).powf(sign as f32);
+
+ let exponent = RADIX.powf(((exponent as i32) - BIAS) as f32);
+
+ let mut mantissa: f32 = 1.0;
+
+ // Mantissa is a sum of 1 + 2^(-1) + 2^(-2) + .. + 2^(-23)
+ for i in 0..23 {
+ let mask = 1 << i;
+ let one_at_bit_i = fraction & mask;
+ if one_at_bit_i != 0 {
+ let i_ = i as f32;
+ let weight = 2_f32.powf(i_ - 23.0);
+ mantissa += weight;
+ }
+ }
+
+ (signed_1, exponent, mantissa)
+}
+
+fn from_parts(sign: f32, exponent: f32, mantissa: f32) -> f32 {
+ sign * exponent * mantissa
+}
+
--- /dev/null
+#![cfg_attr(debug_assertions, allow(dead_code, unused_imports))]
+
+mod decode_f32;
+mod q7;
+mod chip8;
+
+use q7::Q7;
+
+fn test_decode_f32() {
+ let n: f32 = 42.42;
+ decode_f32::print_f32(n);
+}
+
+fn test_q7() {
+ println!("{:?}", Q7::from(0.3))
+}
+
+fn test_chip() {
+
+}
+
+fn main() {
+ // test_decode_f32();
+ // test_q7();
+ test_chip();
+}
--- /dev/null
+/// A type to encode a range from -1 to 1 into 8 bits.
+#[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) -> Self {
+ (n.0 as f64) * 2f64.powf(-7.0) // Same as / 128.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) -> Self {
+ f64::from(n) as f32
+ }
+}
+
+mod tests {
+ use super::*;
+
+ #[test]
+ fn simple_case() {
+ let a = 0.45;
+ assert_eq!(a, (f64::from(Q7::from(a)) * 100.0).round() / 100.0);
+ }
+}
\ No newline at end of file