1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
mod fp_fx;
mod fp_q;
use crate::UInt;
pub use fp_fx::{to_Fx, Fx};
pub use fp_q::{to_Q, Q};
pub trait FixedPoint {
fn eval(&self) -> f64;
}
fn debug_print(val: UInt, m: i32, b: i32, is_exact: bool) -> String {
const ANSI_RESET_COLOR: &str = "\x1b[0m";
const ANSI_BLACK: &str = "\x1b[37;40m"; // bold, black background, white foreground
const ANSI_MAGENTA: &str = "\x1b[45m"; // non bold, magenta background, black foreground
let bits = format!("{:0width$b}", val, width = (b) as usize);
let dots = if is_exact { "" } else { "..." };
let ans = format!(
"{ANSI_MAGENTA}{int}{ANSI_BLACK}{frac}{dots}{ANSI_RESET_COLOR}",
int = &bits[..m as usize],
frac = &bits[m as usize..],
);
ans
}
#[cfg(test)]
mod test {
use crate::fixed_point::Q;
#[test]
fn test_add() {
let fp1 = Q::new(0b1111, 3, 1, true);
let fp2 = Q::new(0b1110, 3, 1, true);
let fp3 = Q::new(0b11101, 4, 1, true);
assert_eq!(fp1 + fp2, fp3);
}
#[test]
fn test_sub() {
let fp1 = Q::new(0b1111, 3, 1, true);
let fp2 = Q::new(0b1110, 3, 1, true);
let fp3 = Q::new(0b0001, 3, 1, true);
assert_eq!(fp1 - fp2, fp3);
}
#[test]
fn test_shift() {
let fp1 = Q::new(0b1111, 3, 1, true);
assert_eq!(fp1 << 1, Q::new(0b1110, 3, 1, true));
assert_eq!(fp1 << 2, Q::new(0b1100, 3, 1, true));
assert_eq!(fp1 << 3, Q::new(0b1000, 3, 1, true));
assert_eq!(fp1 >> 1, Q::new(0b0111, 3, 1, true));
}
// #[test]
// #[ignore]
// fn test_index_right_idx_0() {
// let fp1 = Q::new(0b10010011, 6, 2, true); // 36.75
// let size = (fp1.m + fp1.n) as usize;
// assert_eq!(fp1.index(size..0).is_err(), true);
// assert_eq!(fp1.index(size - 1..0), Ok(Q::new(0b10010011, 6, 2, true)));
// assert_eq!(fp1.index(size - 2..0), Ok(Q::new(0b0010011, 5, 2, true)));
// assert_eq!(fp1.index(size - 3..0), Ok(Q::new(0b010011, 4, 2, true)));
// assert_eq!(fp1.index(size - 4..0), Ok(Q::new(0b10011, 3, 2, true)));
// assert_eq!(fp1.index(size - 5..0), Ok(Q::new(0b0011, 2, 2, true)));
// assert_eq!(fp1.index(size - 6..0), Ok(Q::new(0b011, 1, 2, true)));
// assert_eq!(fp1.index(size - 7..0), Ok(Q::new(0b11, 0, 2, true)));
// // assert_eq!(
// // fp1.index(size - 8..0),
// // Ok(Q::new(0b1, 0, 1, true))
// // );
// // assert_eq!(fp1.index(size - 9..0).is_err(), true);
// }
// #[test]
// #[ignore]
// fn test_index_left_idx_max() {
// let fp1 = Q::new(0b10010011, 6, 2, true); // 36.75
// let size = (fp1.m + fp1.n) as usize;
// assert_eq!(fp1.index(size..0).is_err(), true);
// assert_eq!(fp1.index(size - 1..0), Ok(Q::new(0b10010011, 6, 2, true)));
// assert_eq!(fp1.index(size - 1..1), Ok(Q::new(0b1001001, 6, 1, true)));
// assert_eq!(fp1.index(size - 1..2), Ok(Q::new(0b100100, 6, 0, true)));
// assert_eq!(fp1.index(size - 1..3), Ok(Q::new(0b10010, 5, 0, true)));
// assert_eq!(fp1.index(size - 1..4), Ok(Q::new(0b1001, 4, 0, true)));
// assert_eq!(fp1.index(size - 1..5), Ok(Q::new(0b100, 3, 0, true)));
// assert_eq!(fp1.index(size - 1..6), Ok(Q::new(0b10, 2, 0, true)));
// // assert_eq!(
// // fp1.index(size-1..7),
// // Ok(Q::new(0b1, 1, 0, true))
// // );
// assert_eq!(fp1.index(size - 8..8).is_err(), true);
// }
}