Maraiah/src/durandal/fx32.rs

99 lines
2.1 KiB
Rust
Raw Normal View History

2018-12-13 01:04:09 -08:00
use std::{fmt, fmt::Write, ops};
pub struct Fx32(i32);
impl Fx32
{
const FRACBITS: u32 = 16;
const FRACMASK: u32 = 0xFFFF;
const ONE: i32 = 1 << Fx32::FRACBITS;
pub fn to_bits(&self) -> u32 {self.0 as u32}
pub fn set_bits(&mut self, bits: u32) {self.0 = bits as i32}
pub fn from_bits(bits: u32) -> Fx32 {Fx32(bits as i32)}
pub fn integ(&self) -> i16 {(self.0 >> 16) as i16}
pub fn fract(&self) -> u16 {(self.0 as u32 & Fx32::FRACMASK) as u16}
}
impl ops::Add for Fx32
{
type Output = Fx32;
fn add(self, other: Fx32) -> Fx32 {Fx32(self.0 + other.0)}
}
impl ops::Sub for Fx32
{
type Output = Fx32;
fn sub(self, other: Fx32) -> Fx32 {Fx32(self.0 - other.0)}
}
impl ops::Mul for Fx32
{
type Output = Fx32;
fn mul(self, other: Fx32) -> Fx32
{Fx32((self.0 as i64 * other.0 as i64 / Fx32::ONE as i64) as i32)}
}
impl ops::Div for Fx32
{
type Output = Fx32;
fn div(self, other: Fx32) -> Fx32
{Fx32((self.0 as i64 * Fx32::ONE as i64 / other.0 as i64) as i32)}
}
impl ops::Neg for Fx32
{
type Output = Fx32;
fn neg(self) -> Fx32 {Fx32(-self.0)}
}
impl ops::Not for Fx32
{
type Output = Fx32;
fn not(self) -> Fx32 {Fx32(!self.0)}
}
impl fmt::Display for Fx32
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
let prec = f.precision().unwrap_or(1);
let widt = f.width().unwrap_or(0);
write!(f, "{:widt$}.", self.integ(), widt = widt)?;
let mut k = self.to_bits();
for _ in 0..prec {
k &= Fx32::FRACMASK;
k *= 10;
let d = k >> Fx32::FRACBITS;
let d = d % 10;
f.write_char((d as u8 + b'0') as char)?;
}
Ok(())
}
}
impl fmt::Debug for Fx32
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
let prec = f.precision().unwrap_or(1);
let widt = f.width().unwrap_or(0);
write!(f, "{:widt$}.", self.integ(), widt = widt)?;
let mut k = self.to_bits();
for _ in 0..prec {
k &= Fx32::FRACMASK;
k *= 10;
let d = k >> Fx32::FRACBITS;
let d = d % 10;
f.write_char((d as u8 + b'0') as char)?;
}
Ok(())
}
}
// EOF