Revert breaking commit: https://github.com/oppiliappan/eva/commit/693ff1c1

--- eva-0.3.1/src/fmt.rs	2022-11-08 09:52:05.000000000 +0800
+++ eva-0.3.1/src/fmt.rs	2026-01-05 07:45:20.000000000 +0800
@@ -27,60 +27,67 @@
     }
 }
 
-fn thousand_sep(mut s: String) -> String {
-    let inc = 3;
-    let mut end = s.find('.').unwrap();
-    let sign = if s.starts_with('-') { 1 } else { 0 };
-    for _ in 0..(end - sign - 1) / inc {
-        end -= inc;
-        s.insert(end, ',');
+fn radix_fmt(number: f64, obase: usize) -> Result<String, CalcError> {
+    match (number.is_infinite(), number.is_sign_positive()) {
+        (true, true) => return Ok("inf".to_string()),
+        (true, false) => return Ok("-inf".to_string()),
+        _ => (),
     }
-    s
-}
 
-pub fn pprint(mut ans: f64) {
-    if ans.is_infinite() {
-        println!("{}inf", if ans.is_sign_positive() { "" } else { "-" });
-    } else if ans.is_nan() {
-        println!("nan");
-    } else if CONFIGURATION.base == 10 {
-        // use standard library formatter since it handle printing pretty well
-        let ans = format!("{:.*}", CONFIGURATION.fix, ans);
-        println!("{}", thousand_sep(ans));
-    } else {
-        ans = format!("{:.*}", CONFIGURATION.fix, ans).parse().unwrap();
-        let table: &[u8] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".as_bytes();
-
-        // format integral part of float
-        let mut integral = BigInt::from_f64(ans.abs().trunc()).unwrap();
-        let mut obase_int = String::new();
-        let obaseb = BigInt::from_usize(CONFIGURATION.base as usize).unwrap();
-
-        while integral >= obaseb {
-            obase_int.push(table[(&integral % &obaseb).to_usize().unwrap()] as char);
-            integral /= &obaseb;
-        }
-        obase_int.push(table[integral.to_usize().unwrap()] as char);
-        if ans.is_sign_negative() {
-            obase_int.push('-');
+    if number.is_nan() {
+        return Ok("nan".to_string());
+    }
+
+    let table: Vec<char> = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".chars().collect();
+
+    // format integral part of float
+    let mut integral = BigInt::from_f64(number.abs().trunc()).unwrap();
+    let mut obase_int = String::new();
+    let obaseb = BigInt::from_usize(obase).unwrap();
+
+    while integral >= obaseb {
+        obase_int.push(table[(&integral % &obaseb).to_usize().unwrap()]);
+        integral /= &obaseb;
+    }
+    obase_int.push(table[integral.to_usize().unwrap()]);
+    if number.is_sign_negative() {
+        obase_int.push('-');
+    }
+    let obase_int = obase_int.chars().rev().collect::<String>();
+
+    // format fractional part of float
+    let mut fract = number.abs().fract();
+    let mut obase_fract = String::new();
+    let mut i = 0;
+    loop {
+        fract *= obase as f64;
+        obase_fract.push(table[fract.trunc() as usize]);
+        i += 1;
+        if fract.fract() == 0. || i >= CONFIGURATION.fix {
+            break;
         }
-        let obase_int = obase_int.chars().rev().collect::<String>();
+        fract = fract.fract();
+    }
+    Ok(format!("{}.{}", obase_int, obase_fract))
+}
 
-        // format fractional part of float
-        // TODO: fix conversion with fractional part
-        let mut fract = ans.abs().fract();
-        let mut obase_fract = String::new();
-        let mut i = 0;
-        loop {
-            fract *= CONFIGURATION.base as f64;
-            obase_fract.push(table[fract.trunc() as usize] as char);
-            i += 1;
-            if fract.fract() == 0. || i >= CONFIGURATION.fix {
-                break;
-            }
-            fract = fract.fract();
+fn thousand_sep(inp: &str) -> String {
+    let mut result_string = String::new();
+    for (i, c) in inp.to_string().chars().rev().enumerate() {
+        if i % 3 == 0 && i != 0 && c.to_string() != "-" {
+            result_string.push(',');
         }
-        let ans = format!("{:>10}.{}", obase_int, obase_fract);
-        println!("{}", thousand_sep(ans));
+        result_string.push(c)
+    }
+    result_string.chars().rev().collect::<String>()
+}
+
+pub fn pprint(ans: f64) {
+    let ans_string = radix_fmt(ans, CONFIGURATION.base).unwrap();
+    let ans_vector: Vec<&str> = ans_string.split('.').collect();
+    match ans_vector.len() {
+        1 => println!("{:>10}", thousand_sep(ans_vector[0])),
+        2 => println!("{:>10}.{}", thousand_sep(ans_vector[0]), ans_vector[1]),
+        _ => unreachable!("N-nani?!"),
     }
 }

--- eva-0.3.1/Cargo.toml	2022-11-08 09:52:05.000000000 +0800
+++ eva-0.3.1/Cargo.toml	2026-01-05 07:47:36.000000000 +0800
@@ -15,6 +15,7 @@
 rustyline = { version = "10.0.0", default-features = false }
 clap = { version = "4.0.18", features = ["cargo"] }
 directories = "4.0.1"
+radix_fmt = "1.0.0"
 regex = "1.5.6"
 num = "0.4.0"
 once_cell = "1.12.0"
