#![cfg(feature = "fixed")]
use fixed::types::{I32F96, I64F64};
use the_q::{Dir, Exact, ExactError, Q, Rat, exact_from_fixed, from_fixed_dir, q_from_fixed};
#[test]
fn small_value_is_exact() {
let v = I64F64::from_num(3.5);
let r = from_fixed_dir(v, Dir::Nearest).unwrap();
assert_eq!(r, Rat::new(7, 2).unwrap());
}
#[test]
fn zero_is_zero() {
let v = I64F64::from_num(0);
assert_eq!(from_fixed_dir(v, Dir::Nearest).unwrap(), Rat::zero());
}
#[test]
fn negative_value_is_exact() {
let v = I64F64::from_num(-1.25);
let r = from_fixed_dir(v, Dir::Nearest).unwrap();
assert_eq!(r, Rat::new(-5, 4).unwrap());
}
#[test]
fn generic_over_different_frac_widths_agree_on_the_same_value() {
let a = from_fixed_dir(I64F64::from_num(1.5), Dir::Nearest).unwrap();
let b = from_fixed_dir(I32F96::from_num(1.5), Dir::Nearest).unwrap();
assert_eq!(a, b);
}
#[test]
fn q_saturates_a_huge_value() {
let huge = I64F64::from_num(i64::MAX);
assert_eq!(q_from_fixed(huge), Q::PosSat);
assert_eq!(q_from_fixed(-huge), Q::NegSat);
}
#[test]
fn q_does_not_saturate_a_value_within_budget() {
let v = I64F64::from_num(12345);
assert_eq!(q_from_fixed(v), Q::Number(Rat::new(12345, 1).unwrap()));
}
#[test]
fn exact_matches_dir_when_it_fits() {
let v = I64F64::from_num(-1.25);
let via_exact = exact_from_fixed(v).unwrap();
assert_eq!(via_exact, Exact::new(Rat::new(-5, 4).unwrap()));
}
#[test]
fn exact_refuses_what_dir_would_saturate() {
let huge = I64F64::from_num(i64::MAX);
assert_eq!(exact_from_fixed(huge), Err(ExactError::Inexact));
}