use crate::types::conversion_error::ConversionError;
use crate::types::sci::Sci;
use crate::types::scientific::Scientific;
use crate::types::sign::Sign;
use alloc::string::{String, ToString};
use core::convert::TryFrom;
use core::str::FromStr;
impl TryFrom<f64> for Scientific {
type Error = ConversionError;
fn try_from(value: f64) -> Result<Self, Self::Error> {
if value.is_finite() {
Ok(Scientific {
inner: Sci::from_string(value.to_string())?,
})
} else {
Err(ConversionError::FloatIsNotFinite)
}
}
}
impl From<&Scientific> for f64 {
fn from(value: &Scientific) -> Self {
if value.inner.is_zero() {
0f64
} else if value.inner.exponent1() > f64::MAX_10_EXP as isize {
match value.inner.sign {
Sign::POSITIVE => f64::INFINITY,
Sign::NEGATIVE => f64::NEG_INFINITY,
}
} else if value.inner.exponent1() < f64::MIN_10_EXP as isize {
0f64
} else {
const DIGITS: isize = 18;
let mut str = String::with_capacity(6 + DIGITS as usize);
if value.inner.sign.is_negative() {
str.push('-');
}
for i in 0..value.inner.len.min(DIGITS) {
str.push((b'0' + value.inner.data[i] as u8) as char);
}
str.push('e');
str.push_str(&(value.inner.exponent + (value.inner.len - DIGITS).max(0)).to_string());
f64::from_str(&str).unwrap()
}
}
}
impl TryFrom<f32> for Scientific {
type Error = ConversionError;
fn try_from(value: f32) -> Result<Self, Self::Error> {
if value.is_finite() {
Ok(Scientific {
inner: Sci::from_string(value.to_string())?,
})
} else {
Err(ConversionError::FloatIsNotFinite)
}
}
}
impl From<&Scientific> for f32 {
fn from(value: &Scientific) -> Self {
if value.inner.is_zero() {
0f32
} else if value.inner.exponent1() > f32::MAX_10_EXP as isize {
match value.inner.sign {
Sign::POSITIVE => f32::INFINITY,
Sign::NEGATIVE => f32::NEG_INFINITY,
}
} else if value.inner.exponent1() < f32::MIN_10_EXP as isize {
0f32
} else {
const DIGITS: isize = 10;
let mut str = String::with_capacity(6 + DIGITS as usize);
if value.inner.sign.is_negative() {
str.push('-');
}
for i in 0..value.inner.len.min(DIGITS) {
str.push((b'0' + value.inner.data[i] as u8) as char);
}
str.push('e');
str.push_str(&(value.inner.exponent + (value.inner.len - DIGITS).max(0)).to_string());
f32::from_str(&str).unwrap()
}
}
}