99 lines
2.1 KiB
Rust
99 lines
2.1 KiB
Rust
|
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
|