Compare commits
8 Commits
b1fdbeb3de
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b7619da2f | |||
| 948ac5f297 | |||
| fbef05fcd1 | |||
| b014dd959c | |||
| 7112987742 | |||
| b8652f6784 | |||
| d5b4490eab | |||
| a91bdbaff4 |
@ -1,8 +1,8 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "sigils"
|
name = "sigils"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
description = "A mathematics library."
|
description = "High-performance no_std linear algebra for simulations and embedded flight systems."
|
||||||
keywords = ["sigils", "math"]
|
keywords = ["sigils", "math"]
|
||||||
repository = "https://workshop.cybermages.tech/CyberMages/sigils"
|
repository = "https://workshop.cybermages.tech/CyberMages/sigils"
|
||||||
authors = ["Jason Travis Smith <Myrddin@CyberMages.tech>"]
|
authors = ["Jason Travis Smith <Myrddin@CyberMages.tech>"]
|
||||||
@ -10,5 +10,3 @@ readme = "README.md"
|
|||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
binding = { version = "0.1.0", registry = "cybermages" }
|
|
||||||
pact = { version = "0.1.0", registry = "cybermages" }
|
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
// Sealed with Magistamp.
|
|
||||||
|
|
||||||
use sigils::quaternion::{Quaternion};
|
|
||||||
|
|
||||||
|
|
||||||
pub fn main()
|
|
||||||
{
|
|
||||||
let quat: Quaternion<f64>;
|
|
||||||
|
|
||||||
quat = Quaternion::<f64>::default();
|
|
||||||
println!("Quaternion: {}", quat);
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
// Sealed with Magistamp.
|
|
||||||
|
|
||||||
use sigils::{Constants, Degree, Radian, Trig};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn main()
|
|
||||||
{
|
|
||||||
let mut val: f64;
|
|
||||||
let mut degrees: Degree<f64>;
|
|
||||||
let mut radians: Radian<f64>;
|
|
||||||
|
|
||||||
val = Constants::QUARTER_PI;
|
|
||||||
val *= 6f64;
|
|
||||||
radians = Radian::new(val);
|
|
||||||
degrees = Trig::acos(Trig::cos(radians));
|
|
||||||
|
|
||||||
println!("{:?}", radians);
|
|
||||||
println!("{:?}", degrees);
|
|
||||||
println!("");
|
|
||||||
|
|
||||||
radians = Radian::new(Constants::QUARTER_PI);
|
|
||||||
radians = Trig::acos(Trig::cos(radians));
|
|
||||||
degrees = Degree::from(radians);
|
|
||||||
|
|
||||||
println!("{:?}", radians);
|
|
||||||
println!("{:?}", degrees);
|
|
||||||
println!("");
|
|
||||||
|
|
||||||
degrees = Degree::new(270.0f64);
|
|
||||||
radians = Trig::acos(Trig::cos(degrees));
|
|
||||||
|
|
||||||
println!("{:?}", degrees);
|
|
||||||
println!("{:?}", radians);
|
|
||||||
println!("");
|
|
||||||
|
|
||||||
degrees = Degree::new(90.0f64);
|
|
||||||
degrees = Trig::acos(Trig::cos(degrees));
|
|
||||||
radians = Radian::from(degrees);
|
|
||||||
|
|
||||||
println!("{:?}", degrees);
|
|
||||||
println!("{:?}", radians);
|
|
||||||
println!("");
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
// Sealed with Magistamp.
|
|
||||||
|
|
||||||
use sigils::vector::{EuclideanVector, Vector2, Vector3, Vector4};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn main()
|
|
||||||
{
|
|
||||||
let length: f32;
|
|
||||||
let vec2: Vector2<f64>;
|
|
||||||
let vec3: Vector3<f64>;
|
|
||||||
let vec4: Vector4<f64>;
|
|
||||||
let vector: Vector4<f32>;
|
|
||||||
|
|
||||||
vec2 = Vector2::default();
|
|
||||||
println!("Vector2: {}", vec2);
|
|
||||||
|
|
||||||
vec3 = Vector3::default();
|
|
||||||
println!("Vector3: {}", vec3);
|
|
||||||
|
|
||||||
vec4 = Vector4::default();
|
|
||||||
println!("Vector4: {}", vec4);
|
|
||||||
|
|
||||||
vector = Vector4::new(5.5f32, 5.5f32, 5.5f32, 5.5f32);
|
|
||||||
length = vector.get_length();
|
|
||||||
println!("Vector: {} -- Length: {}", vector, length);
|
|
||||||
assert_eq!(length, 11.0f32);
|
|
||||||
}
|
|
||||||
106
src/bounded.rs
106
src/bounded.rs
@ -1,13 +1,38 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Sealed with Magistamp.
|
// Sealed with Magistamp.
|
||||||
|
|
||||||
/// Primitive types that have upper and lower bounds.
|
/// `Bounded` provides the inclusive minimum and maximum range limits
|
||||||
|
/// for a numeric type.
|
||||||
|
///
|
||||||
|
/// Rust types have actual upper and lower representation limits that don't
|
||||||
|
/// follow the mathematical definitions. For example a Natural number goes
|
||||||
|
/// from one to infinity but a u8 can only really represent a number between
|
||||||
|
/// zero and two hundred and fifty five. This let's use set the minimum and
|
||||||
|
/// maximum values a Rust type can represent so we can use them in code easily.
|
||||||
pub trait Bounded
|
pub trait Bounded
|
||||||
{
|
{
|
||||||
/// The minimum value for this type.
|
/// The minimum value for this type.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```rust
|
||||||
|
/// use sigils::Bounded;
|
||||||
|
///
|
||||||
|
/// let min = <u8 as Bounded>::MIN;
|
||||||
|
///
|
||||||
|
/// assert_eq!(min, u8::MIN);
|
||||||
|
/// ```
|
||||||
const MIN: Self;
|
const MIN: Self;
|
||||||
|
|
||||||
/// The maximum value for this type.
|
/// The maximum value for this type.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```rust
|
||||||
|
/// use sigils::Bounded;
|
||||||
|
///
|
||||||
|
/// let max = <f64 as Bounded>::MAX;
|
||||||
|
///
|
||||||
|
/// assert_eq!(max, f64::MAX);
|
||||||
|
/// ```
|
||||||
const MAX: Self;
|
const MAX: Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,83 +42,20 @@ pub trait Bounded
|
|||||||
/// the Bounded trait easier.
|
/// the Bounded trait easier.
|
||||||
macro_rules! bounded_trait_impl
|
macro_rules! bounded_trait_impl
|
||||||
{
|
{
|
||||||
($T: ty, $minVal: expr, $maxVal: expr) =>
|
($($T:ty),*) =>
|
||||||
{
|
{
|
||||||
|
$(
|
||||||
impl Bounded for $T
|
impl Bounded for $T
|
||||||
{
|
{
|
||||||
const MIN: $T = $minVal;
|
const MIN: $T = <$T>::MIN;
|
||||||
|
const MAX: $T = <$T>::MAX;
|
||||||
const MAX: $T = $maxVal;
|
|
||||||
}
|
}
|
||||||
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Implement the Bounded for all the primitive types.
|
// Implement the Bounded for all the primitive types.
|
||||||
bounded_trait_impl!(u8, 0u8, !0u8);
|
bounded_trait_impl!(u8, u16, u32, u64, u128, usize);
|
||||||
bounded_trait_impl!(u16, 0u16, !0u16);
|
bounded_trait_impl!(i8, i16, i32, i64, i128, isize);
|
||||||
bounded_trait_impl!(u32, 0u32, !0u32);
|
bounded_trait_impl!(f32, f64);
|
||||||
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()
|
|
||||||
{
|
|
||||||
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::<i8>() as i8)*8i8)-1i8),
|
|
||||||
!(-1i8 << (((::std::mem::size_of::<i8>() as i8)*8i8)-1i8)));
|
|
||||||
bounds_test!(i16, min_max_i16,
|
|
||||||
-1i16 << (((::std::mem::size_of::<i16>() as i16)*8i16)-1i16),
|
|
||||||
!(-1i16 << (((::std::mem::size_of::<i16>() as i16)*8i16)-1i16)));
|
|
||||||
bounds_test!(i32, min_max_i32,
|
|
||||||
-1i32 << (((::std::mem::size_of::<i32>() as i32)*8i32)-1i32),
|
|
||||||
!(-1i32 << (((::std::mem::size_of::<i32>() as i32)*8i32)-1i32)));
|
|
||||||
bounds_test!(i64, min_max_i64,
|
|
||||||
-1i64 << (((::std::mem::size_of::<i64>() as i64)*8i64)-1i64),
|
|
||||||
!(-1i64 << (((::std::mem::size_of::<i64>() as i64)*8i64)-1i64)));
|
|
||||||
bounds_test!(isize, min_max_isize,
|
|
||||||
-1isize << (((::std::mem::size_of::<isize>() as isize)*8isize)-1isize),
|
|
||||||
!(-1isize << (((::std::mem::size_of::<isize>() 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);
|
|
||||||
}
|
|
||||||
|
|||||||
40
src/lib.rs
40
src/lib.rs
@ -1,23 +1,38 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Sealed with Magistamp.
|
// Sealed with Magistamp.
|
||||||
|
|
||||||
//! A mathematical library.
|
//! # Sigils
|
||||||
//! License: Proprietary
|
|
||||||
//!
|
//!
|
||||||
|
//! A high performance, 'no_std' mathematical library designed for use in
|
||||||
|
//! simulations and flight systems.
|
||||||
//!
|
//!
|
||||||
|
//! Sigils uses Rust's type system to strictly define a mathematical hierarchy
|
||||||
|
//! to ensure type-safe operations.
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
extern crate core as std;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
mod macros;
|
|
||||||
|
|
||||||
mod bounded;
|
mod bounded;
|
||||||
|
mod natural;
|
||||||
mod zero;
|
|
||||||
mod one;
|
|
||||||
mod number;
|
mod number;
|
||||||
|
mod one;
|
||||||
|
mod zero;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub use self::bounded::Bounded;
|
||||||
|
pub use self::natural::Natural;
|
||||||
|
pub use self::number::Number;
|
||||||
|
pub use self::one::One;
|
||||||
|
pub use self::zero::Zero;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#[macro_use]
|
||||||
|
//mod macros;
|
||||||
|
/*
|
||||||
|
|
||||||
mod whole;
|
mod whole;
|
||||||
mod integer;
|
mod integer;
|
||||||
mod real;
|
mod real;
|
||||||
@ -28,11 +43,9 @@ mod trig;
|
|||||||
pub mod vector;
|
pub mod vector;
|
||||||
pub mod matrix;
|
pub mod matrix;
|
||||||
pub mod quaternion;
|
pub mod quaternion;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
pub use self::bounded::Bounded;
|
|
||||||
pub use self::zero::Zero;
|
|
||||||
pub use self::one::One;
|
pub use self::one::One;
|
||||||
pub use self::number::{Number, FromNumber};
|
pub use self::number::{Number, FromNumber};
|
||||||
pub use self::whole::Whole;
|
pub use self::whole::Whole;
|
||||||
@ -40,3 +53,4 @@ pub use self::integer::Integer;
|
|||||||
pub use self::real::Real;
|
pub use self::real::Real;
|
||||||
pub use self::constants::Constants;
|
pub use self::constants::Constants;
|
||||||
pub use self::trig::{Degree, Radian, Trig};
|
pub use self::trig::{Degree, Radian, Trig};
|
||||||
|
*/
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
// Sealed with Magistamp.
|
|
||||||
|
|
||||||
82
src/natural.rs
Normal file
82
src/natural.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
// Sealed with Magistamp.
|
||||||
|
|
||||||
|
use core::ops::{Add, AddAssign, Mul, MulAssign};
|
||||||
|
|
||||||
|
use crate::number::Number;
|
||||||
|
use crate::one::One;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// A Natural number is a counting number from one to infinity.
|
||||||
|
/// 1, 2, 3, 4, 5, 6, ...
|
||||||
|
///
|
||||||
|
/// Rust types that are in this category are:
|
||||||
|
/// u8, u16, u32, u64, u128, usize
|
||||||
|
pub trait Natural: Number + One +
|
||||||
|
Add<Output=Self> + AddAssign +
|
||||||
|
Mul<Output=Self> + MulAssign +
|
||||||
|
{
|
||||||
|
/// Attempts to subtract a number from itself.
|
||||||
|
///
|
||||||
|
/// Since subtraction isn't closed under this set (1 - 2 = -1) the trait
|
||||||
|
/// doesn't enforce that Sub and SubAssign are implemented. This function,
|
||||||
|
/// however, allows for subtraction and handles the case where the result is
|
||||||
|
/// no longer within the `Natural` numbers domain.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// `rhs`: The number to subtract.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// `None` if the subtraction would fall below 1.
|
||||||
|
/// `Some` if their is a valid result.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```rust
|
||||||
|
/// use sigils::Natural;
|
||||||
|
///
|
||||||
|
/// let x = 3u8 as Natural;
|
||||||
|
///
|
||||||
|
/// assert_eq!(x.try_sub(2), Some(1));
|
||||||
|
/// assert_eq!(x.try_sub(7), None);
|
||||||
|
/// ```
|
||||||
|
fn try_sub(self, rhs: Self) -> Option<Self>;
|
||||||
|
/*
|
||||||
|
///
|
||||||
|
fn try_div(self, rhs: Self) -> Option<Self>;
|
||||||
|
|
||||||
|
///
|
||||||
|
fn try_rem(self, rhs: Self) -> Option<Self>;
|
||||||
|
|
||||||
|
/// Performs division and returns both the quotient and remainder.
|
||||||
|
#[inline]
|
||||||
|
fn try_div_rem(self, rhs: Self) -> Option<(Self, Self)>
|
||||||
|
{
|
||||||
|
Some((self.try_div(rhs)?, self.try_rem(rhs)?))
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// A macro to make implementing the `Natural` trait easier for all the
|
||||||
|
/// base types in Rust.
|
||||||
|
macro_rules! natural_trait_impl
|
||||||
|
{
|
||||||
|
($($varType:ty),*) =>
|
||||||
|
{
|
||||||
|
$(
|
||||||
|
impl Natural for $varType
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn try_sub(self, rhs: Self) -> Option<Self>
|
||||||
|
{
|
||||||
|
self.checked_sub(rhs).filter(|x| *x >= Self::one())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement the Number trait for the types that are Numbers.
|
||||||
|
natural_trait_impl!(u8, u16, u32, u64, u128, usize);
|
||||||
956
src/number.rs
956
src/number.rs
@ -1,42 +1,35 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Sealed with Magistamp.
|
// Sealed with Magistamp.
|
||||||
|
|
||||||
use std::cmp::{PartialEq, PartialOrd};
|
use core::cmp::{PartialEq, PartialOrd};
|
||||||
use std::fmt::{Debug, Display};
|
use core::fmt::{Debug, Display};
|
||||||
use std::mem::size_of;
|
|
||||||
use std::ops::{Add, Sub, Mul, Div, Rem};
|
|
||||||
use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use crate::bounded::Bounded;
|
|
||||||
use crate::zero::Zero;
|
|
||||||
use crate::one::One;
|
|
||||||
|
|
||||||
|
|
||||||
/// A trait that defines what is required to be considered
|
|
||||||
/// a number.
|
/// `Number` helps bridge the gap between the rust implementation and the pure
|
||||||
pub trait Number: Zero + One + Add<Output=Self> + Sub<Output=Self> +
|
/// math definitions.
|
||||||
Mul<Output=Self> + Div<Output=Self> + Rem<Output=Self> +
|
///
|
||||||
AddAssign<Self> + SubAssign<Self> + MulAssign<Self> +
|
/// `Number` has some basic Rust representation requirements.
|
||||||
DivAssign<Self> + RemAssign<Self> + PartialEq + PartialOrd +
|
///
|
||||||
Copy + Clone + Debug + Display
|
/// [`Sized`]: A `Number` has a known size at compile time.
|
||||||
|
/// [`Copy`] & [`Clone`]: A `Number` should be passed by value, not reference.
|
||||||
|
/// [`PartialEq`] & [`PartialOrd`]: Two instances of `Number` should be able to be compared.
|
||||||
|
/// [`Debug`] & [`Display`]: Easier to read output.
|
||||||
|
pub trait Number: Sized + Copy + Clone +
|
||||||
|
PartialEq + PartialOrd +
|
||||||
|
Debug + Display
|
||||||
{
|
{
|
||||||
type StrRadixError;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// The smallest number that can be stored in this type.
|
|
||||||
//const MIN: Self;
|
|
||||||
|
|
||||||
/// The largest number that can be stored in this type.
|
|
||||||
//const MAX: Self;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Returns the maximum of the two numbers.
|
/// Returns the maximum of the two numbers.
|
||||||
///
|
///
|
||||||
/// ```
|
/// # Arguments
|
||||||
/// use ::sigils::Number;
|
/// * `other` - Another value, of the same type, to compare.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// The larger value of the two numbers.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```rust
|
||||||
|
/// use sigils::Number;
|
||||||
///
|
///
|
||||||
/// let x: f64;
|
/// let x: f64;
|
||||||
/// let y: f64;
|
/// let y: f64;
|
||||||
@ -45,12 +38,23 @@ pub trait Number: Zero + One + Add<Output=Self> + Sub<Output=Self> +
|
|||||||
/// y = 2.0f64;
|
/// y = 2.0f64;
|
||||||
/// assert_eq!(x.maximum(y), y);
|
/// assert_eq!(x.maximum(y), y);
|
||||||
/// ```
|
/// ```
|
||||||
fn maximum(self, other: Self) -> Self;
|
#[inline]
|
||||||
|
fn maximum(self, other: Self) -> Self
|
||||||
|
{
|
||||||
|
if self >= other { self } else { other }
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the minimum of the two numbers.
|
/// Returns the minimum of the two numbers.
|
||||||
///
|
///
|
||||||
/// ```
|
/// # Arguments
|
||||||
/// use ::sigils::Number;
|
/// * `other` - Another value, of the same type, to compare.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// The smaller value of the two numbers.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```rust
|
||||||
|
/// use sigils::Number;
|
||||||
///
|
///
|
||||||
/// let x: i16;
|
/// let x: i16;
|
||||||
/// let y: i16;
|
/// let y: i16;
|
||||||
@ -59,883 +63,29 @@ pub trait Number: Zero + One + Add<Output=Self> + Sub<Output=Self> +
|
|||||||
/// y = 55i16;
|
/// y = 55i16;
|
||||||
/// assert_eq!(x.minimum(y), x);
|
/// assert_eq!(x.minimum(y), x);
|
||||||
/// ```
|
/// ```
|
||||||
fn minimum(self, other: Self) -> Self;
|
#[inline]
|
||||||
|
|
||||||
/// Create a number from a given string and base radix.
|
|
||||||
///
|
|
||||||
///```
|
|
||||||
/// // Parse the hex value "FF" into an i32.
|
|
||||||
/// // Hex values have a radix (base) of 16.
|
|
||||||
/// use sigils::Number;
|
|
||||||
///
|
|
||||||
/// let x: i32 = Number::from_str_radix("FF", 16u32).unwrap();
|
|
||||||
/// # assert_eq!(x, 255i32);
|
|
||||||
///```
|
|
||||||
fn from_str_radix(src: &str, radix: u32) ->
|
|
||||||
Result<Self, Self::StrRadixError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A trait that defines converting something to a Number.
|
|
||||||
pub trait ToNumber
|
|
||||||
{
|
|
||||||
/// Convert this to an u8.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn to_u8(&self) -> Option<u8>
|
|
||||||
{
|
|
||||||
let option: Option<u64>;
|
|
||||||
|
|
||||||
option = self.to_u64();
|
|
||||||
match option
|
|
||||||
{
|
|
||||||
Some(val) =>
|
|
||||||
{
|
|
||||||
val.to_u8()
|
|
||||||
}
|
|
||||||
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert this to a u16.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn to_u16(&self) -> Option<u16>
|
|
||||||
{
|
|
||||||
let option: Option<u64>;
|
|
||||||
|
|
||||||
option = self.to_u64();
|
|
||||||
match option
|
|
||||||
{
|
|
||||||
Some(val) =>
|
|
||||||
{
|
|
||||||
val.to_u16()
|
|
||||||
}
|
|
||||||
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert this to an u32.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn to_u32(&self) -> Option<u32>
|
|
||||||
{
|
|
||||||
let option: Option<u64>;
|
|
||||||
|
|
||||||
option = self.to_u64();
|
|
||||||
match option
|
|
||||||
{
|
|
||||||
Some(val) =>
|
|
||||||
{
|
|
||||||
val.to_u32()
|
|
||||||
}
|
|
||||||
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert this to an u64.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn to_u64(&self) -> Option<u64>;
|
|
||||||
|
|
||||||
/// Convert this to an usize.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn to_usize(&self) -> Option<usize>
|
|
||||||
{
|
|
||||||
let option: Option<u64>;
|
|
||||||
|
|
||||||
option = self.to_u64();
|
|
||||||
match option
|
|
||||||
{
|
|
||||||
Some(val) =>
|
|
||||||
{
|
|
||||||
val.to_usize()
|
|
||||||
}
|
|
||||||
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Convert this to an i8.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn to_i8(&self) -> Option<i8>
|
|
||||||
{
|
|
||||||
let option: Option<i64>;
|
|
||||||
|
|
||||||
option = self.to_i64();
|
|
||||||
match option
|
|
||||||
{
|
|
||||||
Some(val) =>
|
|
||||||
{
|
|
||||||
val.to_i8()
|
|
||||||
}
|
|
||||||
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert this to an i16.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn to_i16(&self) -> Option<i16>
|
|
||||||
{
|
|
||||||
let option: Option<i64>;
|
|
||||||
|
|
||||||
option = self.to_i64();
|
|
||||||
match option
|
|
||||||
{
|
|
||||||
Some(val) =>
|
|
||||||
{
|
|
||||||
val.to_i16()
|
|
||||||
}
|
|
||||||
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert this to an i32.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn to_i32(&self) -> Option<i32>
|
|
||||||
{
|
|
||||||
let option: Option<i64>;
|
|
||||||
|
|
||||||
option = self.to_i64();
|
|
||||||
match option
|
|
||||||
{
|
|
||||||
Some(val) =>
|
|
||||||
{
|
|
||||||
val.to_i32()
|
|
||||||
}
|
|
||||||
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert this to an i64.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn to_i64(&self) -> Option<i64>;
|
|
||||||
|
|
||||||
/// Convert this to an isize.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn to_isize(&self) -> Option<isize>
|
|
||||||
{
|
|
||||||
let option: Option<i64>;
|
|
||||||
|
|
||||||
option = self.to_i64();
|
|
||||||
match option
|
|
||||||
{
|
|
||||||
Some(val) =>
|
|
||||||
{
|
|
||||||
val.to_isize()
|
|
||||||
}
|
|
||||||
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Convert this to an f32.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn to_f32(&self) -> Option<f32>
|
|
||||||
{
|
|
||||||
let option: Option<f64>;
|
|
||||||
|
|
||||||
option = self.to_f64();
|
|
||||||
match option
|
|
||||||
{
|
|
||||||
Some(val) =>
|
|
||||||
{
|
|
||||||
val.to_f32()
|
|
||||||
}
|
|
||||||
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert this to an f64.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn to_f64(&self) -> Option<f64>
|
|
||||||
{
|
|
||||||
let option: Option<i64>;
|
|
||||||
|
|
||||||
option = self.to_i64();
|
|
||||||
match option
|
|
||||||
{
|
|
||||||
Some(val) =>
|
|
||||||
{
|
|
||||||
val.to_f64()
|
|
||||||
}
|
|
||||||
|
|
||||||
None =>
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A trait that defines convertung a Number to something else.
|
|
||||||
pub trait FromNumber : Sized
|
|
||||||
{
|
|
||||||
/// Convert an i8 to an optional value of this type.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn from_i8(number: i8) -> Option<Self>
|
|
||||||
{
|
|
||||||
FromNumber::from_i64(number as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert an i16 to an optional value of this type.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn from_i16(number: i16) -> Option<Self>
|
|
||||||
{
|
|
||||||
FromNumber::from_i64(number as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert an i32 to an optional value of this type.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn from_i32(number: i32) -> Option<Self>
|
|
||||||
{
|
|
||||||
FromNumber::from_i64(number as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert an i64 to an optional value of this type.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn from_i64(number: i64) -> Option<Self>;
|
|
||||||
|
|
||||||
/// Convert an isize to an optional value of this type.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn from_isize(number: isize) -> Option<Self>
|
|
||||||
{
|
|
||||||
FromNumber::from_i64(number as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Convert an u8 to an optional value of this type.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn from_u8(number: u8) -> Option<Self>
|
|
||||||
{
|
|
||||||
FromNumber::from_u64(number as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert an u16 to an optional value of this type.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn from_u16(number: u16) -> Option<Self>
|
|
||||||
{
|
|
||||||
FromNumber::from_u64(number as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert an u32 to an optional value of this type.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn from_u32(number: u32) -> Option<Self>
|
|
||||||
{
|
|
||||||
FromNumber::from_u64(number as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert an u64 to an optional value of this type.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn from_u64(number: u64) -> Option<Self>;
|
|
||||||
|
|
||||||
/// Convert an usize to an optional value of this type.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn from_usize(number: usize) -> Option<Self>
|
|
||||||
{
|
|
||||||
FromNumber::from_u64(number as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Convert an f32 to an optional value of this type.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn from_f32(number: f32) -> Option<Self>
|
|
||||||
{
|
|
||||||
FromNumber::from_f64(number as f64)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert an f64 to an optional value of this type.
|
|
||||||
/// None is returned if the conversion is not possible.
|
|
||||||
fn from_f64(number: f64) -> Option<Self>
|
|
||||||
{
|
|
||||||
FromNumber::from_i64(number as i64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Create some macros to ease typing and reading.
|
|
||||||
macro_rules! convert_int_to_int
|
|
||||||
{
|
|
||||||
($srcType: ty, $dstType: ty, $val: expr) =>
|
|
||||||
{
|
|
||||||
{
|
|
||||||
let num: i64;
|
|
||||||
let min_value: $dstType;
|
|
||||||
let max_value: $dstType;
|
|
||||||
|
|
||||||
num = $val as i64;
|
|
||||||
min_value = Bounded::MIN;
|
|
||||||
max_value = Bounded::MAX;
|
|
||||||
|
|
||||||
if (min_value as i64) <= num && num <= (max_value as i64)
|
|
||||||
{
|
|
||||||
Some($val as $dstType)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! convert_int_to_uint
|
|
||||||
{
|
|
||||||
($srcType: ty, $dstType: ty, $val: expr) =>
|
|
||||||
{
|
|
||||||
{
|
|
||||||
let zero: $srcType;
|
|
||||||
let max_value: $dstType;
|
|
||||||
|
|
||||||
zero = Zero::zero();
|
|
||||||
max_value = Bounded::MAX;
|
|
||||||
|
|
||||||
if zero <= $val && ($val as u64) <= (max_value as u64)
|
|
||||||
{
|
|
||||||
Some($val as $dstType)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! convert_uint_to_int
|
|
||||||
{
|
|
||||||
($dstType: ty, $val: expr) =>
|
|
||||||
{
|
|
||||||
{
|
|
||||||
let max_value: $dstType;
|
|
||||||
|
|
||||||
max_value = Bounded::MAX;
|
|
||||||
if ($val as u64) <= (max_value as u64)
|
|
||||||
{
|
|
||||||
Some($val as $dstType)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! convert_uint_to_uint
|
|
||||||
{
|
|
||||||
($srcType: ty, $dstType: ty, $val: expr) =>
|
|
||||||
{
|
|
||||||
if size_of::<$srcType>() <= size_of::<$dstType>()
|
|
||||||
{
|
|
||||||
Some($val as $dstType)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
let zero: $srcType;
|
|
||||||
let max_value: $dstType;
|
|
||||||
|
|
||||||
zero = Zero::zero();
|
|
||||||
max_value = Bounded::MAX;
|
|
||||||
|
|
||||||
if zero <= $val && ($val as u64) <= (max_value as u64)
|
|
||||||
{
|
|
||||||
Some($val as $dstType)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! convert_float_to_float
|
|
||||||
{
|
|
||||||
($srcType: ty, $dstType: ty, $val: expr) =>
|
|
||||||
{
|
|
||||||
if size_of::<$srcType>() <= size_of::<$dstType>()
|
|
||||||
{
|
|
||||||
Some($val as $dstType)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
let num: f64;
|
|
||||||
let min_value: $srcType;
|
|
||||||
let max_value: $srcType;
|
|
||||||
|
|
||||||
num = $val as f64;
|
|
||||||
min_value = Bounded::MIN;
|
|
||||||
max_value = Bounded::MAX;
|
|
||||||
|
|
||||||
if (min_value as f64) <= num && num <= (max_value as f64)
|
|
||||||
{
|
|
||||||
Some($val as $dstType)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! int_to_number_impl
|
|
||||||
{
|
|
||||||
($traitName: ident for $($varType: ty)*) =>
|
|
||||||
($(
|
|
||||||
impl $traitName for $varType
|
|
||||||
{
|
|
||||||
fn to_u8(&self) -> Option<u8>
|
|
||||||
{
|
|
||||||
convert_int_to_uint!($varType, u8, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u16(&self) -> Option<u16>
|
|
||||||
{
|
|
||||||
convert_int_to_uint!($varType, u16, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u32(&self) -> Option<u32>
|
|
||||||
{
|
|
||||||
convert_int_to_uint!($varType, u32, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u64(&self) -> Option<u64>
|
|
||||||
{
|
|
||||||
convert_int_to_uint!($varType, u64, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_usize(&self) -> Option<usize>
|
|
||||||
{
|
|
||||||
convert_int_to_uint!($varType, usize, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn to_i8(&self) -> Option<i8>
|
|
||||||
{
|
|
||||||
convert_int_to_int!($varType, i8, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_i16(&self) -> Option<i16>
|
|
||||||
{
|
|
||||||
convert_int_to_int!($varType, i16, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_i32(&self) -> Option<i32>
|
|
||||||
{
|
|
||||||
convert_int_to_int!($varType, i32, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_i64(&self) -> Option<i64>
|
|
||||||
{
|
|
||||||
convert_int_to_int!($varType, i64, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_isize(&self) -> Option<isize>
|
|
||||||
{
|
|
||||||
convert_int_to_int!($varType, isize, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn to_f32(&self) -> Option<f32>
|
|
||||||
{
|
|
||||||
Some(*self as f32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_f64(&self) -> Option<f64>
|
|
||||||
{
|
|
||||||
Some(*self as f64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! uint_to_number_impl
|
|
||||||
{
|
|
||||||
($traitName: ident for $($varType: ty)*) =>
|
|
||||||
($(
|
|
||||||
impl $traitName for $varType
|
|
||||||
{
|
|
||||||
fn to_u8(&self) -> Option<u8>
|
|
||||||
{
|
|
||||||
convert_uint_to_uint!($varType, u8, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u16(&self) -> Option<u16>
|
|
||||||
{
|
|
||||||
convert_uint_to_uint!($varType, u16, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u32(&self) -> Option<u32>
|
|
||||||
{
|
|
||||||
convert_uint_to_uint!($varType, u32, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u64(&self) -> Option<u64>
|
|
||||||
{
|
|
||||||
convert_uint_to_uint!($varType, u64, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_usize(&self) -> Option<usize>
|
|
||||||
{
|
|
||||||
convert_uint_to_uint!($varType, usize, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn to_i8(&self) -> Option<i8>
|
|
||||||
{
|
|
||||||
convert_uint_to_int!(i8, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_i16(&self) -> Option<i16>
|
|
||||||
{
|
|
||||||
convert_uint_to_int!(i16, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_i32(&self) -> Option<i32>
|
|
||||||
{
|
|
||||||
convert_uint_to_int!(i32, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_i64(&self) -> Option<i64>
|
|
||||||
{
|
|
||||||
convert_uint_to_int!(i64, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_isize(&self) -> Option<isize>
|
|
||||||
{
|
|
||||||
convert_uint_to_int!(isize, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn to_f32(&self) -> Option<f32>
|
|
||||||
{
|
|
||||||
Some(*self as f32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_f64(&self) -> Option<f64>
|
|
||||||
{
|
|
||||||
Some(*self as f64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! float_to_number_impl
|
|
||||||
{
|
|
||||||
($traitName: ident for $($varType: ty)*) =>
|
|
||||||
($(
|
|
||||||
impl $traitName for $varType
|
|
||||||
{
|
|
||||||
fn to_u8(&self) -> Option<u8>
|
|
||||||
{
|
|
||||||
Some(*self as u8)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u16(&self) -> Option<u16>
|
|
||||||
{
|
|
||||||
Some(*self as u16)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u32(&self) -> Option<u32>
|
|
||||||
{
|
|
||||||
Some(*self as u32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u64(&self) -> Option<u64>
|
|
||||||
{
|
|
||||||
Some(*self as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_usize(&self) -> Option<usize>
|
|
||||||
{
|
|
||||||
Some(*self as usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn to_i8(&self) -> Option<i8>
|
|
||||||
{
|
|
||||||
Some(*self as i8)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_i16(&self) -> Option<i16>
|
|
||||||
{
|
|
||||||
Some(*self as i16)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_i32(&self) -> Option<i32>
|
|
||||||
{
|
|
||||||
Some(*self as i32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_i64(&self) -> Option<i64>
|
|
||||||
{
|
|
||||||
Some(*self as i64)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_isize(&self) -> Option<isize>
|
|
||||||
{
|
|
||||||
Some(*self as isize)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn to_f32(&self) -> Option<f32>
|
|
||||||
{
|
|
||||||
convert_float_to_float!($varType, f32, *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_f64(&self) -> Option<f64>
|
|
||||||
{
|
|
||||||
convert_float_to_float!($varType, f64, *self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! from_number_impl
|
|
||||||
{
|
|
||||||
($varType: ty, $toTypeFunc: ident) =>
|
|
||||||
{
|
|
||||||
impl FromNumber for $varType
|
|
||||||
{
|
|
||||||
fn from_u8(number: u8) -> Option<$varType>
|
|
||||||
{
|
|
||||||
number.$toTypeFunc()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_u16(number: u16) -> Option<$varType>
|
|
||||||
{
|
|
||||||
number.$toTypeFunc()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_u32(number: u32) -> Option<$varType>
|
|
||||||
{
|
|
||||||
number.$toTypeFunc()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_u64(number: u64) -> Option<$varType>
|
|
||||||
{
|
|
||||||
number.$toTypeFunc()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn from_i8(number: i8) -> Option<$varType>
|
|
||||||
{
|
|
||||||
number.$toTypeFunc()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_i16(number: i16) -> Option<$varType>
|
|
||||||
{
|
|
||||||
number.$toTypeFunc()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_i32(number: i32) -> Option<$varType>
|
|
||||||
{
|
|
||||||
number.$toTypeFunc()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_i64(number: i64) -> Option<$varType>
|
|
||||||
{
|
|
||||||
number.$toTypeFunc()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn from_f32(number: f32) -> Option<$varType>
|
|
||||||
{
|
|
||||||
number.$toTypeFunc()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_f64(number: f64) -> Option<$varType>
|
|
||||||
{
|
|
||||||
number.$toTypeFunc()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A macro to make implementing the Number trait easier for all the
|
|
||||||
/// base integer types in rust.
|
|
||||||
macro_rules! int_number_trait_impl
|
|
||||||
{
|
|
||||||
($traitName: ident for $varType: ty, $min: expr, $max: expr) =>
|
|
||||||
{
|
|
||||||
impl $traitName for $varType
|
|
||||||
{
|
|
||||||
type StrRadixError = ::std::num::ParseIntError;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//const MIN: Self = $min;
|
|
||||||
//const MAX: Self = $max;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn maximum(self, other: Self) -> Self
|
|
||||||
{
|
|
||||||
if self >= other
|
|
||||||
{
|
|
||||||
self
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
other
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn minimum(self, other: Self) -> Self
|
fn minimum(self, other: Self) -> Self
|
||||||
{
|
{
|
||||||
if self <= other
|
if self <= other { self } else { other }
|
||||||
{
|
|
||||||
self
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
other
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_str_radix(src: &str, radix: u32) ->
|
|
||||||
Result<Self, ::std::num::ParseIntError>
|
|
||||||
{
|
|
||||||
<$varType>::from_str_radix(src, radix)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A macro to make implementing the Number trait easier for all the
|
|
||||||
/// base float types in rust.
|
|
||||||
macro_rules! float_number_trait_impl
|
|
||||||
|
/// A macro to make implementing the `Number` trait easier for all the
|
||||||
|
/// base types in Rust.
|
||||||
|
macro_rules! number_trait_impl
|
||||||
{
|
{
|
||||||
($traitName: ident for $varType: ty, $min: expr, $max: expr,
|
($($varType:ty),*) =>
|
||||||
$minFunc: ident, $maxFunc: ident) =>
|
|
||||||
{
|
{
|
||||||
impl $traitName for $varType
|
$(
|
||||||
{
|
impl Number for $varType {}
|
||||||
type StrRadixError = ::std::num::ParseFloatError;
|
)*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//const MIN: Self = $min;
|
|
||||||
//const MAX: Self = $max;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn maximum(self, other: Self) -> Self
|
|
||||||
{
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
::pact::math::$maxFunc(self, other) as Self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn minimum(self, other: Self) -> Self
|
|
||||||
{
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
::pact::math::$minFunc(self, other) as Self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_str_radix(src: &str, radix: u32) ->
|
|
||||||
Result<Self, ::std::num::ParseFloatError>
|
|
||||||
{
|
|
||||||
// TODO: Currently this will panic on a non base 10 radix.
|
|
||||||
// This is because the std library deprecated the
|
|
||||||
// from_str_radix function. Until a function can be
|
|
||||||
// written this will use the from_str function and
|
|
||||||
// panic for non base 10 requests.
|
|
||||||
assert!(radix == 10);
|
|
||||||
<$varType>::from_str(src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Implement the Number trait for the types that are Numbers.
|
// Implement the Number trait for the types that are Numbers.
|
||||||
int_number_trait_impl!(Number for u8, 0u8, 255u8);
|
number_trait_impl!(u8, u16, u32, u64, u128, usize);
|
||||||
int_number_trait_impl!(Number for u16, 0u16, 65535u16);
|
number_trait_impl!(i8, i16, i32, i64, i128, isize);
|
||||||
int_number_trait_impl!(Number for u32, 0u32, 4294967295u32);
|
number_trait_impl!(f32, f64);
|
||||||
int_number_trait_impl!(Number for u64, 0u64, 18446744073709551615u64);
|
|
||||||
int_number_trait_impl!(Number for i8, -128i8, 127i8);
|
|
||||||
int_number_trait_impl!(Number for i16, -32768i16, 32767i16);
|
|
||||||
int_number_trait_impl!(Number for i32, -2147483648i32, 2147483647i32);
|
|
||||||
int_number_trait_impl!(Number for i64, -9223372036854775808i64,
|
|
||||||
9223372036854775807i64);
|
|
||||||
float_number_trait_impl!(Number for f32, -3.40282347e+38f32,
|
|
||||||
3.40282347e+38f32,
|
|
||||||
fminf, fmaxf);
|
|
||||||
float_number_trait_impl!(Number for f64, -1.7976931348623157e+308f64,
|
|
||||||
1.7976931348623157e+308f64,
|
|
||||||
fmin, fmax);
|
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "16")]
|
|
||||||
int_number_trait_impl!(Number for usize, 0usize, 65535usize);
|
|
||||||
#[cfg(target_pointer_width = "32")]
|
|
||||||
int_number_trait_impl!(Number for usize, 0usize, 4294967295usize);
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
|
||||||
int_number_trait_impl!(Number for usize, 0usize, 18446744073709551615usize);
|
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "16")]
|
|
||||||
int_number_trait_impl!(Number for isize, -32768isize, 32767isize);
|
|
||||||
#[cfg(target_pointer_width = "32")]
|
|
||||||
int_number_trait_impl!(Number for isize, -2147483648isize, 2147483647isize);
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
|
||||||
int_number_trait_impl!(Number for isize, -9223372036854775808isize,
|
|
||||||
9223372036854775807isize);
|
|
||||||
|
|
||||||
// Implement the ToNumber and FromNumber traits for
|
|
||||||
// the types that are Numbers. The FromNumber trait needs
|
|
||||||
// to be defined after ToNumber since FromNumber uses
|
|
||||||
// ToNumber definitions.
|
|
||||||
uint_to_number_impl!(ToNumber for u8 u16 u32 u64 usize);
|
|
||||||
int_to_number_impl!(ToNumber for i8 i16 i32 i64 isize);
|
|
||||||
float_to_number_impl!(ToNumber for f32 f64);
|
|
||||||
|
|
||||||
from_number_impl!(u8, to_u8);
|
|
||||||
from_number_impl!(u16, to_u16);
|
|
||||||
from_number_impl!(u32, to_u32);
|
|
||||||
from_number_impl!(u64, to_u64);
|
|
||||||
from_number_impl!(usize, to_usize);
|
|
||||||
|
|
||||||
from_number_impl!(i8, to_i8);
|
|
||||||
from_number_impl!(i16, to_i16);
|
|
||||||
from_number_impl!(i32, to_i32);
|
|
||||||
from_number_impl!(i64, to_i64);
|
|
||||||
from_number_impl!(isize, to_isize);
|
|
||||||
|
|
||||||
from_number_impl!(f32, to_f32);
|
|
||||||
from_number_impl!(f64, to_f64);
|
|
||||||
|
|||||||
67
src/one.rs
67
src/one.rs
@ -1,10 +1,13 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Sealed with Magistamp.
|
// Sealed with Magistamp.
|
||||||
|
|
||||||
use std::ops::Mul;
|
use core::ops::{Mul, MulAssign};
|
||||||
|
|
||||||
/// Defines a multiplicative identity element for `Self`.
|
|
||||||
pub trait One: Sized + Mul<Self, Output=Self>
|
|
||||||
|
/// Defines a multiplicative identity.
|
||||||
|
pub trait One: Sized + PartialEq +
|
||||||
|
Mul<Self, Output=Self> + MulAssign
|
||||||
{
|
{
|
||||||
/// Returns the multiplicative identity element of `Self`, `1`.
|
/// Returns the multiplicative identity element of `Self`, `1`.
|
||||||
///
|
///
|
||||||
@ -14,44 +17,54 @@ pub trait One: Sized + Mul<Self, Output=Self>
|
|||||||
/// a * 1 = a ∀ a ∈ Self
|
/// a * 1 = a ∀ a ∈ Self
|
||||||
/// 1 * a = a ∀ a ∈ Self
|
/// 1 * a = a ∀ a ∈ Self
|
||||||
/// ```
|
/// ```
|
||||||
|
/// [Multiplicative Identity](https://en.wikipedia.org/wiki/1#In_mathematics)
|
||||||
///
|
///
|
||||||
/// # Purity
|
/// # Purity
|
||||||
///
|
///
|
||||||
/// This function should return the same result at all times regardless of
|
/// This function must be a pure mathematical constant. It should return
|
||||||
/// external mutable state, for example values stored in TLS or in
|
/// the same result at all times regardless of external mutable state, for
|
||||||
/// `static mut`s.
|
/// example values stored in Thread Local Storage(TLS) or in `static mut`s.
|
||||||
fn one() -> Self;
|
fn one() -> Self;
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns `true` if the value is the multiplicative identity.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```rust
|
||||||
|
/// use sigils::One;
|
||||||
|
///
|
||||||
|
/// let x = 1u32;
|
||||||
|
/// assert!(x.is_one());
|
||||||
|
///
|
||||||
|
/// let y = 5f64;
|
||||||
|
/// assert!(!y.is_one());
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
fn is_one(&self) -> bool
|
||||||
|
{
|
||||||
|
*self == Self::one()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
macro_rules! one_impl
|
macro_rules! one_impl
|
||||||
{
|
{
|
||||||
($varType: ty, $val: expr) =>
|
($($varType: ty),*) =>
|
||||||
{
|
{
|
||||||
|
$(
|
||||||
impl One for $varType
|
impl One for $varType
|
||||||
{
|
{
|
||||||
fn one() -> $varType
|
#[inline]
|
||||||
{
|
fn one() -> Self
|
||||||
$val
|
{ 1 as $varType }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implement the One trait for the basic rust types.
|
||||||
|
one_impl!(u8, u16, u32, u64, u128, usize);
|
||||||
one_impl!(u8, 1u8);
|
one_impl!(i8, i16, i32, i64, i128, isize);
|
||||||
one_impl!(u16, 1u16);
|
one_impl!(f32, f64);
|
||||||
one_impl!(u32, 1u32);
|
|
||||||
one_impl!(u64, 1u64);
|
|
||||||
one_impl!(usize, 1usize);
|
|
||||||
|
|
||||||
one_impl!(i8, 1i8);
|
|
||||||
one_impl!(i16, 1i16);
|
|
||||||
one_impl!(i32, 1i32);
|
|
||||||
one_impl!(i64, 1i64);
|
|
||||||
one_impl!(isize, 1isize);
|
|
||||||
|
|
||||||
one_impl!(f32, 1.0f32);
|
|
||||||
one_impl!(f64, 1.0f64);
|
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
// Sealed with Magistamp.
|
|
||||||
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
// Sealed with Magistamp.
|
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ use crate::vector::{EuclideanVector, Vector3};
|
|||||||
|
|
||||||
|
|
||||||
/// A Quaternion is a combination of a scalar and a vector
|
/// A Quaternion is a combination of a scalar and a vector
|
||||||
/// of complex numbers.
|
/// of imaginary units.
|
||||||
///
|
///
|
||||||
/// [S, V] = [S, Xi + Yj + Zk]
|
/// [S, V] = [S, Xi + Yj + Zk]
|
||||||
///
|
///
|
||||||
@ -28,9 +28,9 @@ use crate::vector::{EuclideanVector, Vector3};
|
|||||||
///
|
///
|
||||||
/// | | |
|
/// | | |
|
||||||
/// |:-------:|:-------:|
|
/// |:-------:|:-------:|
|
||||||
/// | ij = 1 | ik = -1 |
|
/// | ij = k | ji = -k |
|
||||||
/// | jk = 1 | kj = -1 |
|
/// | jk = i | kj = -i |
|
||||||
/// | ki = 1 | ji = -1 |
|
/// | ki = j | ik = -j |
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Quaternion<T>
|
pub struct Quaternion<T>
|
||||||
{
|
{
|
||||||
@ -274,6 +274,11 @@ impl<T> Quaternion<T> where T: Trig
|
|||||||
/// conjugate of this Quaternion.
|
/// conjugate of this Quaternion.
|
||||||
pub fn invert(&self) -> Quaternion<T>
|
pub fn invert(&self) -> Quaternion<T>
|
||||||
{
|
{
|
||||||
|
// This only works for unit quaternions and the normalize here is doing
|
||||||
|
// the heavy lifting of fixing my drift for my skeleton rotations.
|
||||||
|
//
|
||||||
|
// JTS: To reuse this code for other domains, this needs to become the
|
||||||
|
// conjugate divided by the magnitude squared.
|
||||||
self.conjugate().normalize()
|
self.conjugate().normalize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
// Sealed with Magistamp.
|
|
||||||
|
|
||||||
68
src/zero.rs
68
src/zero.rs
@ -1,10 +1,13 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Sealed with Magistamp.
|
// Sealed with Magistamp.
|
||||||
|
|
||||||
use std::ops::Add;
|
use core::ops::{Add, AddAssign};
|
||||||
|
|
||||||
/// Defines an additive identity element for `Self`.
|
|
||||||
pub trait Zero: Sized + Add<Self, Output=Self>
|
|
||||||
|
/// Defines an additive identity.
|
||||||
|
pub trait Zero: Sized + PartialEq +
|
||||||
|
Add<Self, Output=Self> + AddAssign
|
||||||
{
|
{
|
||||||
/// Returns the additive identity element of `Self`, `0`.
|
/// Returns the additive identity element of `Self`, `0`.
|
||||||
///
|
///
|
||||||
@ -14,44 +17,55 @@ pub trait Zero: Sized + Add<Self, Output=Self>
|
|||||||
/// a + 0 = a ∀ a ∈ Self
|
/// a + 0 = a ∀ a ∈ Self
|
||||||
/// 0 + a = a ∀ a ∈ Self
|
/// 0 + a = a ∀ a ∈ Self
|
||||||
/// ```
|
/// ```
|
||||||
|
/// [Additive Identity](https://en.wikipedia.org/wiki/Additive_identity)
|
||||||
///
|
///
|
||||||
/// # Purity
|
/// # Purity
|
||||||
///
|
///
|
||||||
/// This function should return the same result at all times regardless of
|
/// This function must be a pure mathematical constant. It should return
|
||||||
/// external mutable state, for example values stored in TLS or in
|
/// the same result at all times regardless of external mutable state, for
|
||||||
/// `static mut`s.
|
/// example values stored in Thread Local Storage(TLS) or in `static mut`s.
|
||||||
fn zero() -> Self;
|
fn zero() -> Self;
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns `true` if the value is the additive identity.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```rust
|
||||||
|
/// use sigils::Zero;
|
||||||
|
///
|
||||||
|
/// let x = 0u32;
|
||||||
|
/// assert!(x.is_zero());
|
||||||
|
///
|
||||||
|
/// let y = 5u64;
|
||||||
|
/// assert!(!y.is_zero());
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
fn is_zero(&self) -> bool
|
||||||
|
{
|
||||||
|
*self == Self::zero()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// A macro to make implementing the `Zero` trait easier for all the
|
||||||
|
/// base types in Rust.
|
||||||
macro_rules! zero_impl
|
macro_rules! zero_impl
|
||||||
{
|
{
|
||||||
($varType: ty, $val: expr) =>
|
($($varType: ty),*) =>
|
||||||
{
|
{
|
||||||
|
$(
|
||||||
impl Zero for $varType
|
impl Zero for $varType
|
||||||
{
|
{
|
||||||
fn zero() -> $varType
|
#[inline]
|
||||||
{
|
fn zero() -> Self
|
||||||
$val
|
{ 0 as $varType }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implement the Zero trait for the basic rust types.
|
||||||
|
zero_impl!(u8, u16, u32, u64, u128, usize);
|
||||||
zero_impl!(u8, 0u8);
|
zero_impl!(i8, i16, i32, i64, i128, isize);
|
||||||
zero_impl!(u16, 0u16);
|
zero_impl!(f32, f64);
|
||||||
zero_impl!(u32, 0u32);
|
|
||||||
zero_impl!(u64, 0u64);
|
|
||||||
zero_impl!(usize, 0usize);
|
|
||||||
|
|
||||||
zero_impl!(i8, 0i8);
|
|
||||||
zero_impl!(i16, 0i16);
|
|
||||||
zero_impl!(i32, 0i32);
|
|
||||||
zero_impl!(i64, 0i64);
|
|
||||||
zero_impl!(isize, 0isize);
|
|
||||||
|
|
||||||
zero_impl!(f32, 0.0f32);
|
|
||||||
zero_impl!(f64, 0.0f64);
|
|
||||||
|
|||||||
@ -1,98 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
// Sealed with Magistamp.
|
|
||||||
|
|
||||||
use std::{f32, f64};
|
|
||||||
use sigils::Constants;
|
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn constant_check_f32()
|
|
||||||
{
|
|
||||||
let val: f32 = Constants::SQRT_2;
|
|
||||||
assert_eq!(val, f32::consts::SQRT_2);
|
|
||||||
let val: f32 = Constants::SQRT_3;
|
|
||||||
assert_eq!(val, 1.73205080756887729352f32);
|
|
||||||
let val: f32 = Constants::INVERSE_SQRT_2;
|
|
||||||
assert_eq!(val, 1.0f32 / f32::consts::SQRT_2);
|
|
||||||
let val: f32 = Constants::INVERSE_SQRT_3;
|
|
||||||
assert_eq!(val, 1.0f32 / 1.73205080756887729352f32);
|
|
||||||
|
|
||||||
let val: f32 = Constants::E;
|
|
||||||
assert_eq!(val, f32::consts::E);
|
|
||||||
|
|
||||||
let val: f32 = Constants::LOG2_E;
|
|
||||||
assert_eq!(val, f32::consts::LOG2_E);
|
|
||||||
let val: f32 = Constants::LOG10_E;
|
|
||||||
assert_eq!(val, f32::consts::LOG10_E);
|
|
||||||
let val: f32 = Constants::LOGE_2;
|
|
||||||
assert_eq!(val, 2f32.ln());
|
|
||||||
let val: f32 = Constants::LOGE_10;
|
|
||||||
assert_eq!(val, 10f32.ln());
|
|
||||||
|
|
||||||
let val: f32 = Constants::TWO_PI;
|
|
||||||
assert_eq!(val, 2f32 * f32::consts::PI);
|
|
||||||
let val: f32 = Constants::PI;
|
|
||||||
assert_eq!(val, f32::consts::PI);
|
|
||||||
let val: f32 = Constants::HALF_PI;
|
|
||||||
assert_eq!(val, f32::consts::PI / 2f32);
|
|
||||||
let val: f32 = Constants::THIRD_PI;
|
|
||||||
assert_eq!(val, f32::consts::PI / 3f32);
|
|
||||||
let val: f32 = Constants::QUARTER_PI;
|
|
||||||
assert_eq!(val, f32::consts::PI / 4f32);
|
|
||||||
let val: f32 = Constants::SIXTH_PI;
|
|
||||||
assert_eq!(val, f32::consts::PI / 6f32);
|
|
||||||
let val: f32 = Constants::EIGHTH_PI;
|
|
||||||
assert_eq!(val, f32::consts::PI / 8f32);
|
|
||||||
let val: f32 = Constants::INVERSE_PI;
|
|
||||||
assert_eq!(val, 1.0f32 / f32::consts::PI);
|
|
||||||
let val: f32 = Constants::TWO_INVERSE_PI;
|
|
||||||
assert_eq!(val, 2.0f32 / f32::consts::PI);
|
|
||||||
let val: f32 = Constants::TWO_INVERSE_SQRT_PI;
|
|
||||||
assert_eq!(val, 2.0f32 / (f32::consts::PI).sqrt());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn constant_check_f64()
|
|
||||||
{
|
|
||||||
let val: f64 = Constants::SQRT_2;
|
|
||||||
assert_eq!(val, f64::consts::SQRT_2);
|
|
||||||
let val: f64 = Constants::SQRT_3;
|
|
||||||
assert_eq!(val, 1.73205080756887729352f64);
|
|
||||||
let val: f64 = Constants::INVERSE_SQRT_2;
|
|
||||||
assert_eq!(val, 1.0f64 / f64::consts::SQRT_2);
|
|
||||||
let val: f64 = Constants::INVERSE_SQRT_3;
|
|
||||||
assert_eq!(val, 1.0f64 / 1.73205080756887729352f64);
|
|
||||||
|
|
||||||
let val: f64 = Constants::E;
|
|
||||||
assert_eq!(val, f64::consts::E);
|
|
||||||
|
|
||||||
let val: f64 = Constants::LOG2_E;
|
|
||||||
assert_eq!(val, f64::consts::LOG2_E);
|
|
||||||
let val: f64 = Constants::LOG10_E;
|
|
||||||
assert_eq!(val, f64::consts::LOG10_E);
|
|
||||||
let val: f64 = Constants::LOGE_2;
|
|
||||||
assert_eq!(val, 2f64.ln());
|
|
||||||
let val: f64 = Constants::LOGE_10;
|
|
||||||
assert_eq!(val, 10f64.ln());
|
|
||||||
|
|
||||||
let val: f64 = Constants::TWO_PI;
|
|
||||||
assert_eq!(val, 2f64 * f64::consts::PI);
|
|
||||||
let val: f64 = Constants::PI;
|
|
||||||
assert_eq!(val, f64::consts::PI);
|
|
||||||
let val: f64 = Constants::HALF_PI;
|
|
||||||
assert_eq!(val, f64::consts::PI / 2f64);
|
|
||||||
let val: f64 = Constants::THIRD_PI;
|
|
||||||
assert_eq!(val, f64::consts::PI / 3f64);
|
|
||||||
let val: f64 = Constants::QUARTER_PI;
|
|
||||||
assert_eq!(val, f64::consts::PI / 4f64);
|
|
||||||
let val: f64 = Constants::SIXTH_PI;
|
|
||||||
assert_eq!(val, f64::consts::PI / 6f64);
|
|
||||||
let val: f64 = Constants::EIGHTH_PI;
|
|
||||||
assert_eq!(val, f64::consts::PI / 8f64);
|
|
||||||
let val: f64 = Constants::INVERSE_PI;
|
|
||||||
assert_eq!(val, 1.0f64 / f64::consts::PI);
|
|
||||||
let val: f64 = Constants::TWO_INVERSE_PI;
|
|
||||||
assert_eq!(val, 2.0f64 / f64::consts::PI);
|
|
||||||
let val: f64 = Constants::TWO_INVERSE_SQRT_PI;
|
|
||||||
assert_eq!(val, 2.0f64 / (f64::consts::PI).sqrt());
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
// Sealed with Magistamp.
|
|
||||||
|
|
||||||
mod constants;
|
|
||||||
mod vector;
|
|
||||||
615
tests/vector.rs
615
tests/vector.rs
@ -1,615 +0,0 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
// Sealed with Magistamp.
|
|
||||||
|
|
||||||
use std::ops::{Add, Sub, Mul, Div, Rem};
|
|
||||||
use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
|
|
||||||
use sigils::vector::*;
|
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vector_creation()
|
|
||||||
{
|
|
||||||
let v: Vector3<f32> = Vector3::<f32>::from_value(1.0f32);
|
|
||||||
|
|
||||||
assert_eq!(v.x, 1.0f32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vector_add()
|
|
||||||
{
|
|
||||||
let v: Vector3<f32> = Vector3::<f32>::from_value(1.0f32);
|
|
||||||
|
|
||||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(4.0f32);
|
|
||||||
let scalar: f32 = 4.0f32;
|
|
||||||
|
|
||||||
let v_three = v.add(&v_two);
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = v.add(v_two);
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = v + &v_two;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = v + v_two;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = &v + &v_two;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = &v + v_two;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = &v + 4.0f32;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = v + 4.0f32;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = &v + scalar;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = v + scalar;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = &v + &scalar;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = v + &scalar;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vector_sub()
|
|
||||||
{
|
|
||||||
let v: Vector3<f32> = Vector3::<f32>::from_value(9.0f32);
|
|
||||||
|
|
||||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(4.0f32);
|
|
||||||
let scalar: f32 = 4.0f32;
|
|
||||||
|
|
||||||
let v_three = v.sub(&v_two);
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = v.sub(v_two);
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = v - &v_two;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = v - v_two;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = &v - &v_two;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = &v - v_two;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = &v - 4.0f32;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = v - 4.0f32;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = &v - scalar;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = v - scalar;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = &v - &scalar;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let v_three = v - &scalar;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vector_mul()
|
|
||||||
{
|
|
||||||
let v: Vector3<f32> = Vector3::<f32>::from_value(3.0f32);
|
|
||||||
|
|
||||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(5.0f32);
|
|
||||||
let scalar: f32 = 5.0f32;
|
|
||||||
|
|
||||||
let v_three = v.mul(&v_two);
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let v_three = v.mul(v_two);
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let v_three = v * &v_two;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let v_three = v * v_two;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let v_three = &v * &v_two;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let v_three = &v * v_two;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let v_three = &v * 5.0f32;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let v_three = v * 5.0f32;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let v_three = &v * scalar;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let v_three = v * scalar;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let v_three = &v * &scalar;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let v_three = v * &scalar;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vector_div()
|
|
||||||
{
|
|
||||||
let v: Vector3<f32> = Vector3::<f32>::from_value(15.0f32);
|
|
||||||
|
|
||||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(5.0f32);
|
|
||||||
let scalar: f32 = 5.0f32;
|
|
||||||
|
|
||||||
let v_three = v.div(&v_two);
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = v.div(v_two);
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = v / &v_two;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = v / v_two;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = &v / &v_two;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = &v / v_two;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = &v / 5.0f32;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = v / 5.0f32;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = &v / scalar;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = v / scalar;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = &v / &scalar;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = v / &scalar;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vector_rem()
|
|
||||||
{
|
|
||||||
let v: Vector3<f32> = Vector3::<f32>::from_value(15.0f32);
|
|
||||||
|
|
||||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(6.0f32);
|
|
||||||
let scalar: f32 = 6.0f32;
|
|
||||||
|
|
||||||
let v_three = v.rem(&v_two);
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = v.rem(v_two);
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = v % &v_two;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = v % v_two;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = &v % &v_two;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = &v % v_two;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = &v % 6.0f32;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = v % 6.0f32;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = &v % scalar;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = v % scalar;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = &v % &scalar;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let v_three = v % &scalar;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vector_add_assign()
|
|
||||||
{
|
|
||||||
let v: Vector3<f32> = Vector3::<f32>::from_value(1.0f32);
|
|
||||||
|
|
||||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(4.0f32);
|
|
||||||
let scalar: f32 = 4.0f32;
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three.add_assign(&v_two);
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three.add_assign(v_two);
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three += &v_two;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three += v_two;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three += 4.0f32;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three += scalar;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three += &scalar;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vector_sub_assign()
|
|
||||||
{
|
|
||||||
let v: Vector3<f32> = Vector3::<f32>::from_value(9.0f32);
|
|
||||||
|
|
||||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(4.0f32);
|
|
||||||
let scalar: f32 = 4.0f32;
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three.sub_assign(&v_two);
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three.sub_assign(v_two);
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three -= &v_two;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three -= v_two;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three -= 4.0f32;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three -= scalar;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three -= &scalar;
|
|
||||||
assert_eq!(v_three.x, 5.0f32);
|
|
||||||
assert_eq!(v_three.y, 5.0f32);
|
|
||||||
assert_eq!(v_three.z, 5.0f32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vector_mul_assign()
|
|
||||||
{
|
|
||||||
let v: Vector3<f32> = Vector3::<f32>::from_value(3.0f32);
|
|
||||||
|
|
||||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(5.0f32);
|
|
||||||
let scalar: f32 = 5.0f32;
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three.mul_assign(&v_two);
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three.mul_assign(v_two);
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three *= &v_two;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three *= v_two;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three *= 5.0f32;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three*= scalar;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three *= &scalar;
|
|
||||||
assert_eq!(v_three.x, 15.0f32);
|
|
||||||
assert_eq!(v_three.y, 15.0f32);
|
|
||||||
assert_eq!(v_three.z, 15.0f32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vector_div_assign()
|
|
||||||
{
|
|
||||||
let v: Vector3<f32> = Vector3::<f32>::from_value(15.0f32);
|
|
||||||
|
|
||||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(5.0f32);
|
|
||||||
let scalar: f32 = 5.0f32;
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three.div_assign(&v_two);
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three.div_assign(v_two);
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three /= &v_two;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three /= v_two;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three /= 5.0f32;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three /= scalar;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three /= &scalar;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn vector_rem_assign()
|
|
||||||
{
|
|
||||||
let v: Vector3<f32> = Vector3::<f32>::from_value(15.0f32);
|
|
||||||
|
|
||||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(6.0f32);
|
|
||||||
let scalar: f32 = 6.0f32;
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three.rem_assign(&v_two);
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three.rem_assign(v_two);
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three %= &v_two;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three %= v_two;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three %= 6.0f32;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three %= scalar;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
|
|
||||||
let mut v_three = v.clone();
|
|
||||||
v_three %= &scalar;
|
|
||||||
assert_eq!(v_three.x, 3.0f32);
|
|
||||||
assert_eq!(v_three.y, 3.0f32);
|
|
||||||
assert_eq!(v_three.z, 3.0f32);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user