i think the debug finally works right?

This commit is contained in:
Lokathor 2022-10-22 20:12:49 -06:00
parent b51f559646
commit 2ecf62e06e
2 changed files with 75 additions and 5 deletions

View file

@ -59,6 +59,19 @@ extern "C" fn main() -> ! {
if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Debug) { if let Ok(mut logger) = MgbaBufferedLogger::try_new(MgbaMessageLevel::Debug) {
writeln!(logger, "hello!").ok(); writeln!(logger, "hello!").ok();
let fx_u: Fixed<u32, 8> =
Fixed::<u32, 8>::wrapping_from(7) + Fixed::<u32, 8>::from_raw(12);
writeln!(logger, "fixed unsigned: {fx_u:?}").ok();
let fx_i1: Fixed<i32, 8> =
Fixed::<i32, 8>::wrapping_from(8) + Fixed::<i32, 8>::from_raw(15);
writeln!(logger, "fixed signed positive: {fx_i1:?}").ok();
let fx_i2: Fixed<i32, 8> = Fixed::<i32, 8>::wrapping_from(0)
- Fixed::<i32, 8>::wrapping_from(3)
- Fixed::<i32, 8>::from_raw(17);
writeln!(logger, "fixed signed negative: {fx_i2:?}").ok();
} }
{ {

View file

@ -25,7 +25,7 @@ pub type i32fx8 = Fixed<i32, 8>;
/// should be *less than* the number of bits in the integer's type. Multiply /// should be *less than* the number of bits in the integer's type. Multiply
/// and divide ops need to shift the value by `B`, and so if `B` is greater /// and divide ops need to shift the value by `B`, and so if `B` is greater
/// than or equal to the integer's size the op will panic. /// than or equal to the integer's size the op will panic.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)] #[repr(transparent)]
pub struct Fixed<I, const B: u32>(I); pub struct Fixed<I, const B: u32>(I);
@ -205,7 +205,7 @@ impl_common_fixed_ops!(u16);
impl_common_fixed_ops!(u32); impl_common_fixed_ops!(u32);
macro_rules! impl_signed_fixed_ops { macro_rules! impl_signed_fixed_ops {
($t:ty) => { ($t:ty, $unsigned:ty) => {
impl<const B: u32> Fixed<$t, B> { impl<const B: u32> Fixed<$t, B> {
/// Negate. /// Negate.
#[inline] #[inline]
@ -214,6 +214,13 @@ macro_rules! impl_signed_fixed_ops {
Self(-self.0) Self(-self.0)
} }
/// If the number is negative or not.
#[inline]
#[must_use]
pub const fn is_negative(self) -> bool {
self.0 < 0
}
/// Multiply. /// Multiply.
#[inline] #[inline]
#[must_use] #[must_use]
@ -230,13 +237,41 @@ macro_rules! impl_signed_fixed_ops {
let d = m / (rhs.0 as i32); let d = m / (rhs.0 as i32);
Self(d as $t) Self(d as $t)
} }
/// Fractional part of the value.
#[inline]
#[must_use]
pub const fn fract(self) -> Self {
let frac_mask = (<$unsigned>::MAX >> (<$t>::BITS - B));
Self((self.0.unsigned_abs() & frac_mask) as $t)
}
/// Whole part of the value.
#[inline]
#[must_use]
pub const fn trunc(self) -> Self {
Self(((self.0.unsigned_abs() >> B) << B) as $t)
}
} }
impl_trait_op_unit!($t, Neg, neg); impl_trait_op_unit!($t, Neg, neg);
impl<const B: u32> core::fmt::Debug for Fixed<$t, B> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
let whole: $t = self.trunc().into_raw() >> B;
let fract: $t = self.fract().into_raw();
let divisor: $t = 1 << B;
if self.is_negative() {
let whole = whole.unsigned_abs();
write!(f, "-({whole}+{fract}/{divisor})")
} else {
write!(f, "{whole}+{fract}/{divisor}")
}
}
}
}; };
} }
impl_signed_fixed_ops!(i8); impl_signed_fixed_ops!(i8, u8);
impl_signed_fixed_ops!(i16); impl_signed_fixed_ops!(i16, u16);
impl_signed_fixed_ops!(i32); impl_signed_fixed_ops!(i32, u32);
macro_rules! impl_unsigned_fixed_ops { macro_rules! impl_unsigned_fixed_ops {
($t:ty) => { ($t:ty) => {
@ -257,6 +292,28 @@ macro_rules! impl_unsigned_fixed_ops {
let d = m / (rhs.0 as u32); let d = m / (rhs.0 as u32);
Self(d as $t) Self(d as $t)
} }
/// Fractional part of the value.
#[inline]
#[must_use]
pub const fn fract(self) -> Self {
Self(self.0 & (<$t>::MAX >> (<$t>::BITS - B)))
}
/// Whole part of the value.
#[inline]
#[must_use]
pub const fn trunc(self) -> Self {
Self(self.0 & (<$t>::MAX << B))
}
}
impl<const B: u32> core::fmt::Debug for Fixed<$t, B> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
let whole: $t = self.trunc().into_raw() >> B;
let fract: $t = self.fract().into_raw();
let divisor: $t = 1 << B;
write!(f, "{whole}+{fract}/{divisor}")
}
} }
}; };
} }