From 164c5df92b6c14907dd4c1a82a911f509a11ae19 Mon Sep 17 00:00:00 2001 From: Hexa Dust Date: Fri, 18 Jul 2025 21:19:30 +0100 Subject: [PATCH] display --- Cargo.lock | 7 +++++ Cargo.toml | 3 ++ src/lib.rs | 80 ++++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 78 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd6d115..42484f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "autocfg" version = "1.4.0" @@ -12,6 +18,7 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" name = "calc-math" version = "0.1.0" dependencies = [ + "arrayvec", "num-traits", ] diff --git a/Cargo.toml b/Cargo.toml index 00e1e29..cabf607 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,3 +5,6 @@ edition = "2021" [dependencies] num-traits = { version = "0.2.19", default-features = false } + +[dev-dependencies] +arrayvec = { version = "0.7.6", default-features = false } diff --git a/src/lib.rs b/src/lib.rs index f6364c5..c8262af 100644 --- a/src/lib.rs +++ b/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 { pub minus: bool, @@ -24,19 +40,22 @@ impl Default for Decimal { } } -#[derive(Debug)] -pub enum DecimalError { - ExponentOverflow, - NotANumber, -} - -impl Error for DecimalError {} -impl Display for DecimalError { +impl Display for Decimal { 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 TryFrom> 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()); + } }