mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 00:31:34 +11:00
fixed point numbers
This commit is contained in:
parent
841d6d5508
commit
0e7c9ad5c1
|
@ -13,6 +13,7 @@ pub mod input;
|
|||
mod interrupt;
|
||||
mod memory_mapped;
|
||||
pub mod mgba;
|
||||
pub mod number;
|
||||
mod single;
|
||||
|
||||
pub mod syscall;
|
||||
|
|
86
src/number.rs
Normal file
86
src/number.rs
Normal file
|
@ -0,0 +1,86 @@
|
|||
use core::{
|
||||
fmt::Display,
|
||||
ops::{Add, Div, Mul, Neg, Sub},
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Num<const N: usize>(i32);
|
||||
|
||||
impl<const N: usize> From<i32> for Num<N> {
|
||||
fn from(value: i32) -> Self {
|
||||
Num(value << N)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Add for Num<N> {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Num<N>) -> Self::Output {
|
||||
Num(self.0 + rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Sub for Num<N> {
|
||||
type Output = Self;
|
||||
fn sub(self, rhs: Num<N>) -> Self::Output {
|
||||
Num(self.0 - rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Mul for Num<N> {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: Num<N>) -> Self::Output {
|
||||
if N % 2 == 0 {
|
||||
Num((self.0 >> (N / 2)) * (rhs.0 >> (N / 2)))
|
||||
} else {
|
||||
Num((self.0 >> (1 + N / 2)) * (rhs.0 >> (N / 2)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Div for Num<N> {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: Num<N>) -> Self::Output {
|
||||
if N % 2 == 0 {
|
||||
Num((self.0 << (N / 2)) / (rhs.0 >> (N / 2)))
|
||||
} else {
|
||||
Num((self.0 << (1 + N / 2)) / (rhs.0 >> (N / 2)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Neg for Num<N> {
|
||||
type Output = Self;
|
||||
fn neg(self) -> Self::Output {
|
||||
Num(-self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Num<N> {
|
||||
pub fn max() -> Self {
|
||||
Num(i32::MAX)
|
||||
}
|
||||
pub fn min() -> Self {
|
||||
Num(i32::MIN)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Display for Num<N> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let integral = self.0 >> N;
|
||||
let mask: u32 = (1 << N) - 1;
|
||||
|
||||
write!(f, "{}", integral)?;
|
||||
|
||||
let mut fractional = self.0 as u32 & mask;
|
||||
if fractional & mask != 0 {
|
||||
write!(f, ".")?;
|
||||
}
|
||||
while fractional & mask != 0 {
|
||||
fractional *= 10;
|
||||
write!(f, "{}", (fractional & !mask) >> N)?;
|
||||
fractional &= mask;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue