use crate::defs::Error;
use crate::ext::ExactNum;
use crate::Consts;
use crate::Radix;
use crate::RoundingMode;
use core::ops::{Deref, DerefMut};
#[cfg(not(feature = "std"))]
use alloc::string::String;
#[derive(Debug, Clone)]
pub struct RadixFloat {
value: ExactNum,
radix: Radix,
}
impl RadixFloat {
pub fn new(value: ExactNum, radix: Radix) -> Result<Self, Error> {
let _ = Radix::try_new(radix.value())?;
Ok(Self { value, radix })
}
pub fn with_radix(value: ExactNum, radix: Radix) -> Self {
Self { value, radix }
}
pub fn value(&self) -> &ExactNum {
&self.value
}
pub const fn radix(&self) -> Radix {
self.radix
}
pub fn into_inner(self) -> ExactNum {
self.value
}
pub fn parse(
s: &str,
radix: Radix,
p: usize,
rm: RoundingMode,
cc: &mut Consts,
) -> Result<Self, Error> {
Radix::try_new(radix.value())?;
Ok(Self {
value: ExactNum::parse(s, radix, p, rm, cc),
radix,
})
}
pub fn format(&self, rm: RoundingMode, cc: &mut Consts) -> Result<String, Error> {
self.value.format(self.radix, rm, cc)
}
}
impl Deref for RadixFloat {
type Target = ExactNum;
fn deref(&self) -> &ExactNum {
&self.value
}
}
impl DerefMut for RadixFloat {
fn deref_mut(&mut self) -> &mut ExactNum {
&mut self.value
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_radix_float_roundtrip() {
let mut cc = Consts::new().unwrap();
let rdx = Radix::try_new(12).unwrap();
let p = 128;
let rm = RoundingMode::ToEven;
let n = ExactNum::parse("10.5", Radix::Dec, p, rm, &mut cc);
let rf = RadixFloat::with_radix(n.clone(), rdx);
let s = rf.format(rm, &mut cc).unwrap();
let g = RadixFloat::parse(&s, rdx, p, rm, &mut cc).unwrap();
assert_eq!(n.cmp(g.value()), Some(0));
}
}