Files
lzf1/src/finum.rs

134 lines
3.0 KiB
Rust
Raw Normal View History

2024-07-26 16:54:03 -04:00
use std::ops::{Add, Sub, Mul, Div, AddAssign, SubAssign};
use std::cmp::Ordering;
#[derive(Debug, Copy, Clone)]
pub struct FiNum(u64);
impl FiNum {
pub fn new_str(s: &str) -> Self {
match s.parse::<f64>() {
Ok(n) => Self::new((n*4294967296.0) as u64),
Err(_e) => Self::zero(),
}
}
pub fn new(value: u64) -> Self {
FiNum(value)
}
pub fn new_i32(value: i32) -> Self {
FiNum((value as u64)<<32)
}
pub fn zero() -> Self {
FiNum(0u64)
}
2024-08-06 18:10:48 -04:00
pub fn one() -> Self {
FiNum(1u64<<32)
}
pub fn infinity() -> Self {
FiNum(u64::MAX)
}
2024-08-14 18:53:55 -04:00
pub fn is_tiny(self) -> bool {
self.0>0u64 && self.0<=1u64
}
2024-07-26 16:54:03 -04:00
pub fn is_zero(self) -> bool {
self.0==0
}
pub fn value(&self) -> u64 {
self.0
}
pub fn recip(&self) -> Self {
FiNum((0x8000000000000000u64/self.0)<<1)
}
2025-01-13 13:34:26 -05:00
pub fn fmt_pct2(&self) -> String {
format!("{:>5.2}%", (100.0*(self.0 as f64))/((1u64<<32) as f64))
}
2024-08-06 18:10:48 -04:00
pub fn fmt_recip(&self) -> String {
if *self<FiNum::one() { format!("1/{}",self.recip()) }
else { format!("{}",self) }
}
2024-07-26 16:54:03 -04:00
pub fn serialize(&self) -> String {
format!("{:X}",self.0)
}
pub fn new_deserialize(s: &str) -> Self {
FiNum(u64::from_str_radix(s, 16).unwrap())
}
}
impl From<i32> for FiNum {
fn from(value:i32) -> Self {
FiNum::new((value as u64)<<32)
}
}
impl PartialEq for FiNum {
fn eq(&self, other:&Self) -> bool {
self.0==other.0
}
}
impl Eq for FiNum { }
impl PartialOrd for FiNum {
fn partial_cmp(&self, other:&Self) -> Option<Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl Ord for FiNum {
fn cmp(&self, other:&Self) -> Ordering {
self.0.cmp(&other.0)
}
}
impl Add for FiNum {
type Output=Self;
fn add(self, other: Self) -> Self {
FiNum(self.0+other.0)
}
}
impl AddAssign for FiNum {
fn add_assign(&mut self, other: Self) {
self.0+=other.0;
}
}
impl Sub for FiNum {
type Output=Self;
fn sub(self, other: Self) -> Self {
FiNum(self.0-other.0)
}
}
impl SubAssign for FiNum {
fn sub_assign(&mut self, other: Self) {
self.0-=other.0;
}
}
impl Mul for FiNum {
type Output=Self;
fn mul(self, other: Self) -> Self {
FiNum(((self.value() as u128)*(other.value() as u128)>>32) as u64)
}
}
impl Div for FiNum {
type Output=Self;
fn div(self,other:Self) -> Self {
let ip=(self.value() as u128)/(other.value() as u128);
let rp=(self.value() as u128)%(other.value() as u128);
let fp=(rp<<32)/(other.value() as u128);
FiNum(((ip<<32)|fp) as u64)
}
}
impl std::fmt::Display for FiNum {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2025-01-13 13:34:26 -05:00
// write!(f, "{:08X}.{:08X}", self.0>>32,self.0&0xFFFFFFFF)
2024-07-26 16:54:03 -04:00
write!(f, "{:.8}", (self.0 as f64)/((1u64<<32) as f64))
}
}