display
This commit is contained in:
80
src/lib.rs
80
src/lib.rs
@@ -1,10 +1,26 @@
|
||||
// #![no_std]
|
||||
#![no_std]
|
||||
|
||||
use core::{error::Error, fmt::Display};
|
||||
#[cfg(not(test))]
|
||||
use num_traits::float::FloatCore;
|
||||
use num_traits::{one, zero, PrimInt, Unsigned};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DecimalError {
|
||||
ExponentOverflow,
|
||||
NotANumber,
|
||||
}
|
||||
|
||||
impl Error for DecimalError {}
|
||||
impl Display for DecimalError {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
DecimalError::ExponentOverflow => f.write_str("Exponent overflow"),
|
||||
DecimalError::NotANumber => f.write_str("Not a number"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Decimal<const S: usize = 5, E = u16> {
|
||||
pub minus: bool,
|
||||
@@ -24,19 +40,22 @@ impl<const S: usize, E: PrimInt> Default for Decimal<S, E> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DecimalError {
|
||||
ExponentOverflow,
|
||||
NotANumber,
|
||||
}
|
||||
|
||||
impl Error for DecimalError {}
|
||||
impl Display for DecimalError {
|
||||
impl<const S: usize, E: Display> Display for Decimal<S, E> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
DecimalError::ExponentOverflow => f.write_str("Exponent overflow"),
|
||||
DecimalError::NotANumber => f.write_str("Not a number"),
|
||||
if self.minus {
|
||||
write!(f, "-")?;
|
||||
}
|
||||
for i in 0..S {
|
||||
write!(f, "{}", self.significant[i])?;
|
||||
if i == 0 {
|
||||
write!(f, ".")?;
|
||||
}
|
||||
}
|
||||
write!(f, "e")?;
|
||||
if self.minus_exponent {
|
||||
write!(f, "-")?;
|
||||
}
|
||||
write!(f, "{}", self.exponent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,6 +139,7 @@ impl<const S: usize, E: PrimInt + Unsigned> TryFrom<Decimal<S, E>> for f64 {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use arrayvec::ArrayString;
|
||||
|
||||
#[test]
|
||||
fn float_to_decimal_zero() {
|
||||
@@ -259,4 +279,40 @@ mod tests {
|
||||
let dec = Decimal::<16>::try_from(f64::MAX).unwrap();
|
||||
assert_eq!(f64::try_from(dec).unwrap(), f64::MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decimal_display_zero() {
|
||||
use core::fmt::Write;
|
||||
let dec = Decimal::<7>::try_from(0.0).unwrap();
|
||||
let mut str: ArrayString<100> = ArrayString::new();
|
||||
write!(str, "{}", dec).unwrap();
|
||||
assert_eq!("0.000000e0", str.as_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decimal_display_pos_big() {
|
||||
use core::fmt::Write;
|
||||
let dec = Decimal::<7>::try_from(1337.42).unwrap();
|
||||
let mut str: ArrayString<100> = ArrayString::new();
|
||||
write!(str, "{}", dec).unwrap();
|
||||
assert_eq!("1.337420e3", str.as_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decimal_display_neg_big() {
|
||||
use core::fmt::Write;
|
||||
let dec = Decimal::<7>::try_from(-1337.42).unwrap();
|
||||
let mut str: ArrayString<100> = ArrayString::new();
|
||||
write!(str, "{}", dec).unwrap();
|
||||
assert_eq!("-1.337420e3", str.as_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decimal_display_neg_small() {
|
||||
use core::fmt::Write;
|
||||
let dec = Decimal::<7>::try_from(-0.0133742).unwrap();
|
||||
let mut str: ArrayString<100> = ArrayString::new();
|
||||
write!(str, "{}", dec).unwrap();
|
||||
assert_eq!("-1.337420e-2", str.as_str());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user