From 7e8ee5ed9cad6484e9f13f81731b102ced58402e Mon Sep 17 00:00:00 2001
From: Adam Carpenter <gitlab@53hor.net>
Date: Tue, 9 Jul 2019 15:14:04 -0400
Subject: Init.

---
 meap/meap-code/ch5/ch5-q/Cargo.lock | 127 ++++++++++++++++++++++++++++++++++++
 meap/meap-code/ch5/ch5-q/Cargo.toml |   7 ++
 meap/meap-code/ch5/ch5-q/src/lib.rs |  76 +++++++++++++++++++++
 3 files changed, 210 insertions(+)
 create mode 100755 meap/meap-code/ch5/ch5-q/Cargo.lock
 create mode 100755 meap/meap-code/ch5/ch5-q/Cargo.toml
 create mode 100755 meap/meap-code/ch5/ch5-q/src/lib.rs

(limited to 'meap/meap-code/ch5/ch5-q')

diff --git a/meap/meap-code/ch5/ch5-q/Cargo.lock b/meap/meap-code/ch5/ch5-q/Cargo.lock
new file mode 100755
index 0000000..3ac932f
--- /dev/null
+++ b/meap/meap-code/ch5/ch5-q/Cargo.lock
@@ -0,0 +1,127 @@
+[root]
+name = "ch5-q"
+version = "0.1.0"
+dependencies = [
+ "num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "bitflags"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "fuchsia-zircon"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "fuchsia-zircon-sys"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "num"
+version = "0.1.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-bigint 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-complex 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-rational 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-bigint"
+version = "0.1.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-complex"
+version = "0.1.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-iter"
+version = "0.1.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-rational"
+version = "0.1.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-bigint 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.1.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rand"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc-serialize"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[metadata]
+"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
+"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
+"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
+"checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2"
+"checksum num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "a311b77ebdc5dd4cf6449d81e4135d9f0e3b153839ac90e648a8ef538f923525"
+"checksum num-bigint 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "8fd0f8dbb4c0960998958a796281d88c16fbe68d87b1baa6f31e2979e81fd0bd"
+"checksum num-complex 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "503e668405c5492d67cf662a81e05be40efe2e6bcf10f7794a07bd9865e704e6"
+"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba"
+"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01"
+"checksum num-rational 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "288629c76fac4b33556f4b7ab57ba21ae202da65ba8b77466e6d598e31990790"
+"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0"
+"checksum rand 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "61efcbcd9fa8d8fbb07c84e34a8af18a1ff177b449689ad38a6e9457ecc7b2ae"
+"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
diff --git a/meap/meap-code/ch5/ch5-q/Cargo.toml b/meap/meap-code/ch5/ch5-q/Cargo.toml
new file mode 100755
index 0000000..ffd0826
--- /dev/null
+++ b/meap/meap-code/ch5/ch5-q/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "ch5-q"
+version = "0.1.0"
+authors = ["Tim McNamara <code@timmcnamara.co.nz>"]
+
+[dependencies]
+num = "*"
\ No newline at end of file
diff --git a/meap/meap-code/ch5/ch5-q/src/lib.rs b/meap/meap-code/ch5/ch5-q/src/lib.rs
new file mode 100755
index 0000000..d05ca3a
--- /dev/null
+++ b/meap/meap-code/ch5/ch5-q/src/lib.rs
@@ -0,0 +1,76 @@
+/// Q1_7 - single byte representation of a fixed point number with range [-1, 1]. 
+/// The name refers to the Texas Instrument representation
+/// 
+/// References:
+///  - English Wikipedia: "Q (number format)" https://en.wikipedia.org/wiki/Q_(number_format)
+#[derive(Debug,Clone,Copy,PartialEq,Eq)]
+pub struct Q7(i8); // tuple struct holding a i8 value
+
+impl From<f64> for Q7 {
+    fn from (n: f64) -> Self {
+        if n >= 1.0 { // out of bounds numbers are coerced to the maximum of the range
+            Q7(127)
+        } else if n <= -1.0 {
+            Q7(-128)
+        } else {
+            Q7((n * 128.0) as i8) // 128 == (2 ** 7) ==  pow(2,7)
+        }
+    }
+}
+
+impl From<Q7> for f64 {
+    fn from(n: Q7) -> f64 {
+        (n.0 as f64) * 2f64.powf(-7.0) // 0.0078125// (2 ** -7) // pow(2, -7)
+    }
+}
+
+impl From<f32> for Q7 {
+    fn from (n: f32) -> Self {
+        Q7::from(n as f64) // conversion from f32 to f64 works perfectly
+    }
+}
+
+impl From<Q7> for f32 {
+    fn from(n: Q7) -> f32 {
+        f64::from(n) as f32 // conversion from f64 to f32 can result in undefined behavior, 
+                            // but not here as f32 can represent all values representable by Q7
+    }
+}
+
+#[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 = -0.4;
+        let q2 = Q7::from(n2);
+
+        let n3 = 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);   // numbers that can be represented exactly by Q7
+        let n2 = f32::from(q2);  // can survive the transition between Q7 and f32
+        assert_eq!(n1, n2);
+    }
+}
-- 
cgit v1.2.3