diff options
| author | Rose Hogenson <rosehogenson@posteo.net> | 2024-05-28 18:12:22 -0700 |
|---|---|---|
| committer | Rose Hogenson <rosehogenson@posteo.net> | 2024-05-28 18:28:53 -0700 |
| commit | ecffc89f29a7d80c362935f9af66deae213fcabc (patch) | |
| tree | 70e2c9d07f842342fc4a63658d38b50fdc77550c /src | |
| parent | Implement modulo. (diff) | |
| download | qc-ecffc89f29a7d80c362935f9af66deae213fcabc.tar.zst | |
Fix a performance issue in the UI.
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval.rs | 42 | ||||
| -rw-r--r-- | src/main.rs | 11 |
2 files changed, 40 insertions, 13 deletions
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}") + } } } } diff --git a/src/main.rs b/src/main.rs index 08c1ded..9fe62b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,7 +34,7 @@ fn main() -> ExitCode { let grid = Grid::new(); window.set_child(Some(&grid)); - let input = Entry::new(); + let input = Entry::builder().width_request(300).build(); grid.attach(&input, 0, 0, 1, 1); let output = Entry::builder().editable(false).build(); @@ -59,6 +59,7 @@ fn main() -> ExitCode { window.add_controller(key_controller); glib::spawn_future_local(async move { + let mut prev_input = String::from(""); loop { if ping_recv.recv().await.is_err() { break; @@ -66,17 +67,21 @@ fn main() -> ExitCode { let Some(input) = get_mail(mailbox.as_ref()) else { continue; }; + if input == prev_input { + continue; + } + prev_input = input.clone(); let (output_send, output_recv) = async_channel::bounded(1); let thread_handle = gtk4::gio::spawn_blocking(move || { if let Some(result) = parser::parse(&input) { - output_send.send_blocking(result).unwrap(); + output_send.send_blocking(format!("{result}")).unwrap(); } }); let _ = thread_handle.await; let Ok(result) = output_recv.try_recv() else { continue; }; - output.set_text(&format!("{result}")); + output.set_text(&result); } }); |
