Created
July 25, 2026 10:32
-
-
Save kaleidawave/49e44e297adfa65dd12046f50b06511b to your computer and use it in GitHub Desktop.
Fixed point data structure + traits
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pub struct Fixed<const N: u8>(u32); | |
| impl<const N: u8> Fixed<N> { | |
| pub const fn from_float(f: f32) -> Self { | |
| let value = (f * 10u32.pow(N as u32) as f32) as u32; | |
| Self(value) | |
| } | |
| } | |
| impl<const N: u8> std::fmt::Display for Fixed<N> { | |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { | |
| let value: u32 = self.0; | |
| if value == 0 { | |
| f.write_str("0") | |
| } else { | |
| let big: u8 = value.ilog10() as u8; | |
| for i in (N..=big).rev() { | |
| let value = value / 10u32.pow(i.into()); | |
| let j = (value as u32) % 10; | |
| f.write_str(&"0123456789"[j as usize..][..1])?; | |
| } | |
| let after = value % 10_u32.pow(N.into()); | |
| if after != 0 { | |
| f.write_str(".")?; | |
| for i in (0..=after.ilog10()).rev() { | |
| let part = value / 10u32.pow(i as u32); | |
| let j = (part % 10) as usize; | |
| f.write_str(&"0123456789"[j..][..1])?; | |
| // TODO better way of cutting trailing zeros | |
| if value == part * 10u32.pow(i as u32) { | |
| break; | |
| } | |
| } | |
| } | |
| Ok(()) | |
| } | |
| } | |
| } | |
| impl<const N: u8> std::fmt::Debug for Fixed<N> { | |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { | |
| std::fmt::Display::fmt(self, f) | |
| } | |
| } | |
| impl<const N: u8> std::ops::Add for Fixed<N> { | |
| type Output = Self; | |
| fn add(self, rhs: Self) -> Self::Output { | |
| Self(self.0 + rhs.0) | |
| } | |
| } | |
| impl<const N: u8> std::ops::Sub for Fixed<N> { | |
| type Output = Self; | |
| fn sub(self, rhs: Self) -> Self::Output { | |
| Self(self.0 - rhs.0) | |
| } | |
| } | |
| impl<const N: u8> std::ops::Mul for Fixed<N> { | |
| type Output = Self; | |
| fn mul(self, rhs: Self) -> Self::Output { | |
| Self(self.0 * rhs.0) | |
| } | |
| } | |
| impl<const N: u8> std::ops::Div for Fixed<N> { | |
| type Output = Self; | |
| fn div(self, rhs: Self) -> Self::Output { | |
| Self(self.0 * rhs.0) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment