From ecffc89f29a7d80c362935f9af66deae213fcabc Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Tue, 28 May 2024 18:12:22 -0700 Subject: Fix a performance issue in the UI. --- src/eval.rs | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) (limited to 'src/eval.rs') diff --git a/src/eval.rs b/src/eval.rs index e07bec2..470bae6 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -194,19 +194,41 @@ impl Num { } } -fn format_float(f: f64) -> String { - let mut s = format!("{f:.7}"); - while let Some(b'0') = s.as_bytes().get(s.len() - 1) { - s.truncate(s.len() - 1); - } - s -} - impl Display for Num { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { match self { - Num::Int(n) => write!(f, "{n}"), - Num::Float(n) => write!(f, "{}", format_float(*n)), + Num::Int(n) => { + if n.bits() < 100 { + return write!(f, "{n}"); + } + let buf = format!("{n}"); + let rounding_factor = BigInt::from(10).pow(buf.len() - 8); + let (mut rounded, rem) = n.div_mod_floor(&rounding_factor); + match rem.cmp(&(rounding_factor / 2)) { + Ordering::Greater => rounded += 1, + Ordering::Equal if rounded.is_odd() => rounded += 1, + _ => (), + } + let rounded_str = format!("{rounded}"); + write!( + f, + "{}.{}e{}", + &rounded_str[..1], + &rounded_str[1..], + buf.len() - 1 + ) + } + Num::Float(n) => { + let n = *n; + if !(-1e30..=1e30).contains(&n) { + return write!(f, "{n:.7e}"); + } + let mut buf = format!("{n:.7}"); + while let Some(b'0') = buf.as_bytes().get(buf.len() - 1) { + buf.truncate(buf.len() - 1); + } + write!(f, "{buf}") + } } } } -- cgit v1.3.1