use sim_kernel::Symbol;
use crate::domains;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct MachineLimits {
pub epsilon: Option<f64>,
pub minimum: Option<f64>,
pub maximum: Option<f64>,
pub minimum_positive: Option<f64>,
}
pub fn machine_limits(domain: &Symbol) -> Option<MachineLimits> {
if domain == &domains::f64() {
Some(MachineLimits {
epsilon: Some(f64::EPSILON),
minimum: Some(f64::MIN),
maximum: Some(f64::MAX),
minimum_positive: Some(f64::MIN_POSITIVE),
})
} else if domain == &domains::f32() {
Some(MachineLimits {
epsilon: Some(f32::EPSILON as f64),
minimum: Some(f32::MIN as f64),
maximum: Some(f32::MAX as f64),
minimum_positive: Some(f32::MIN_POSITIVE as f64),
})
} else if domain == &domains::i64() {
Some(MachineLimits {
epsilon: Some(1.0),
minimum: Some(i64::MIN as f64),
maximum: Some(i64::MAX as f64),
minimum_positive: Some(1.0),
})
} else if domain == &domains::rational() {
Some(MachineLimits {
epsilon: None,
minimum: None,
maximum: None,
minimum_positive: None,
})
} else {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn fixed_and_exact_domain_limits_are_explicit() {
assert_eq!(
machine_limits(&domains::f32()).unwrap().epsilon,
Some(f32::EPSILON as f64)
);
assert_eq!(
machine_limits(&domains::i64()).unwrap().minimum_positive,
Some(1.0)
);
assert_eq!(machine_limits(&domains::rational()).unwrap().epsilon, None);
}
}