Add implementation of rem_euclid stolen from f32's implementation and add a test

This commit is contained in:
Gwilym Kuiper 2021-06-05 17:27:00 +01:00
parent cdaef51d76
commit 363a16ce33

View file

@ -142,6 +142,19 @@ impl<const N: usize> Num<N> {
} }
} }
pub fn rem_euclid(&self, rhs: Self) -> Self {
let r = *self % rhs;
if r < 0.into() {
if rhs < 0.into() {
r - rhs
} else {
r + rhs
}
} else {
r
}
}
pub fn new(integral: i32) -> Self { pub fn new(integral: i32) -> Self {
Self(integral << N) Self(integral << N)
} }
@ -250,6 +263,31 @@ fn test_rem_returns_sensible_values_for_non_integers(_gba: &mut super::Gba) {
} }
} }
#[test_case]
fn test_rem_euclid_is_always_positive_and_sensible(_gba: &mut super::Gba) {
let one: Num<8> = 1.into();
let third = one / 3;
for i in -50..50 {
for j in -50..50 {
if j == 0 {
continue;
}
// full calculation in the normal way
let x: Num<8> = third + i;
let y: Num<8> = j.into();
let truncated_division: Num<8> = (x / y).int().into();
let remainder = x - truncated_division * y;
let rem_euclid = x.rem_euclid(y);
assert!(rem_euclid > 0.into());
}
}
}
impl<const N: usize> Display for Num<N> { impl<const N: usize> Display for Num<N> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let integral = self.0 >> N; let integral = self.0 >> N;