aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/eval.rs17
1 files changed, 7 insertions, 10 deletions
diff --git a/src/eval.rs b/src/eval.rs
index 470bae6..1045b17 100644
--- a/src/eval.rs
+++ b/src/eval.rs
@@ -1,6 +1,5 @@
use num::pow::Pow;
use num::{BigInt, FromPrimitive, Integer, Signed, ToPrimitive};
-use std::cmp::Ordering;
use std::fmt::{Display, Formatter};
pub enum Num {
@@ -194,6 +193,10 @@ impl Num {
}
}
+fn log10(n: &BigInt) -> u64 {
+ ((n.bits() - 1) as f64 / std::f64::consts::LOG2_10) as u64
+}
+
impl Display for Num {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
@@ -201,21 +204,15 @@ impl Display for Num {
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 len = log10(n) + 1;
+ let rounded = i64::try_from(n / BigInt::from(10).pow(len - 8)).unwrap();
let rounded_str = format!("{rounded}");
write!(
f,
"{}.{}e{}",
&rounded_str[..1],
&rounded_str[1..],
- buf.len() - 1
+ len - 8 + rounded_str.len() as u64 - 1
)
}
Num::Float(n) => {