diff --git a/src/bounded.rs b/src/bounded.rs new file mode 100644 index 0000000..a3cdfbb --- /dev/null +++ b/src/bounded.rs @@ -0,0 +1,100 @@ +/// Primitive types that have upper and lower bounds. +pub trait Bounded +{ + /// The minimum value for this type. + const MIN: Self; + + /// The maximum value for this type. + const MAX: Self; +} + + + +/// A macro for making implementation of +/// the Bounded trait easier. +macro_rules! bounded_trait_impl +{ + ($T: ty, $minVal: expr, $maxVal: expr) => + { + impl Bounded for $T + { + const MIN: $T = $minVal; + + const MAX: $T = $maxVal; + } + } +} + + +// Implement the Bounded for all the primitive types. +bounded_trait_impl!(u8, 0u8, !0u8); +bounded_trait_impl!(u16, 0u16, !0u16); +bounded_trait_impl!(u32, 0u32, !0u32); +bounded_trait_impl!(u64, 0u64, !0u64); +bounded_trait_impl!(usize, 0usize, !0usize); + +bounded_trait_impl!(i8, (!0i8 ^ (!0u8 >> 1u8) as i8), + !(!0i8 ^ (!0u8 >> 1u8) as i8)); +bounded_trait_impl!(i16, (!0i16 ^ (!0u16 >> 1u16) as i16), + !(!0i16 ^ (!0u16 >> 1u16) as i16)); +bounded_trait_impl!(i32, (!0i32 ^ (!0u32 >> 1u32) as i32), + !(!0i32 ^ (!0u32 >> 1u32) as i32)); +bounded_trait_impl!(i64, (!0i64 ^ (!0u64 >> 1u64) as i64), + !(!0i64 ^ (!0u64 >> 1u64) as i64)); +bounded_trait_impl!(isize, (!0isize ^ (!0usize >> 1usize) as isize), + !(!0isize ^ (!0usize >> 1usize) as isize)); + +bounded_trait_impl!(f32, -3.40282347e+38f32, 3.40282347e+38f32); +bounded_trait_impl!(f64, -1.7976931348623157e+308f64, + 1.7976931348623157e+308f64); + + + +#[cfg(test)] +mod tests +{ + macro_rules! bounds_test + { + ($T: ident, $func_name: ident, $minVal: expr, $maxVal: expr) => + { + #[test] + fn $func_name() + { + use bounded::Bounded; + + + + assert_eq!($T::MIN, $minVal); + assert_eq!($T::MAX, $maxVal); + } + } + } + + bounds_test!(u8, min_max_u8, 0u8, !0u8); + bounds_test!(u16, min_max_u16, 0u16, !0u16); + bounds_test!(u32, min_max_u32, 0u32, !0u32); + bounds_test!(u64, min_max_u64, 0u64, !0u64); + bounds_test!(usize, min_max_usize, 0usize, !0usize); + + bounds_test!(i8, min_max_i8, + -1i8 << (((::std::mem::size_of::() as i8)*8i8)-1i8), + !(-1i8 << (((::std::mem::size_of::() as i8)*8i8)-1i8))); + bounds_test!(i16, min_max_i16, + -1i16 << (((::std::mem::size_of::() as i16)*8i16)-1i16), + !(-1i16 << (((::std::mem::size_of::() as i16)*8i16)-1i16))); + bounds_test!(i32, min_max_i32, + -1i32 << (((::std::mem::size_of::() as i32)*8i32)-1i32), + !(-1i32 << (((::std::mem::size_of::() as i32)*8i32)-1i32))); + bounds_test!(i64, min_max_i64, + -1i64 << (((::std::mem::size_of::() as i64)*8i64)-1i64), + !(-1i64 << (((::std::mem::size_of::() as i64)*8i64)-1i64))); + bounds_test!(isize, min_max_isize, + -1isize << (((::std::mem::size_of::() as isize)*8isize)-1isize), + !(-1isize << (((::std::mem::size_of::() as isize)*8isize)-1isize))); + + bounds_test!(f32, min_max_f32, + -3.40282347e+38f32, 3.40282347e+38f32); + bounds_test!(f64, min_max_f64, + -1.7976931348623157e+308f64, + 1.7976931348623157e+308f64); +} diff --git a/src/lib.rs b/src/lib.rs index 5ecca94..ecdd716 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,8 @@ extern crate core as std; #[macro_use] mod macros; +mod bounded; + mod zero; mod one; mod number; @@ -26,6 +28,7 @@ pub mod quaternion; +pub use self::bounded::Bounded; pub use self::zero::Zero; pub use self::one::One; pub use self::number::Number; diff --git a/src/number.rs b/src/number.rs index d669a34..b2026e9 100644 --- a/src/number.rs +++ b/src/number.rs @@ -5,8 +5,7 @@ use std::ops::{Add, Sub, Mul, Div, Rem}; use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign}; use std::str::FromStr; -use weave::Bounded; - +use crate::bounded::Bounded; use crate::zero::Zero; use crate::one::One; diff --git a/src/real.rs b/src/real.rs index 691f191..a712748 100644 --- a/src/real.rs +++ b/src/real.rs @@ -646,18 +646,18 @@ impl Real for f32 const NEG_INFINITY: Self = -1.0f32 / 0.0f32; /// - const NAN: Self = 0.0f32 / 0.0f32; + const NAN: Self = f32::NAN; fn is_nan(self) -> bool { - self == Self::NAN + self.is_nan() } fn is_finite(self) -> bool { - !self.is_infinite() && self != Self::NAN + !self.is_infinite() && !self.is_nan() } fn is_infinite(self) -> bool @@ -908,18 +908,18 @@ impl Real for f64 const NEG_INFINITY: Self = -1.0f64 / 0.0f64; /// - const NAN: Self = 0.0f64 / 0.0f64; + const NAN: Self = f64::NAN; fn is_nan(self) -> bool { - self == Self::NAN + self.is_nan() } fn is_finite(self) -> bool { - !self.is_infinite() && self != Self::NAN + !self.is_infinite() && !self.is_nan() } fn is_infinite(self) -> bool