diff --git a/apps/gridcraft-cli/src/main.rs b/apps/gridcraft-cli/src/main.rs index 972c023fa..5170ba0c5 100644 --- a/apps/gridcraft-cli/src/main.rs +++ b/apps/gridcraft-cli/src/main.rs @@ -195,7 +195,18 @@ fn pretty(v: &Value) -> String { /// A number as a person would type it: `6`, `0.5`, `1e+300`. fn number_text(n: f64) -> String { - if n.fract() == 0.0 && n.abs() < 1e15 { format!("{}", n as i64) } else { format!("{n}") } + if n.fract() == 0.0 && n.abs() < 1e15 { + format!("{}", n as i64) + } else if n.is_finite() && (n.abs() >= 1e15 || n.abs() < 1e-5) { + // Rust's `Display` never uses exponent form; `{:e}` omits the `+` on positive exponents. + let s = format!("{n:e}"); + match s.split_once('e') { + Some((m, e)) if !e.starts_with('-') => format!("{m}e+{e}"), + _ => s, + } + } else { + format!("{n}") + } } /// A computed value (as returned by `formulas.evaluate` / `sheet.read`) as plain text. @@ -606,6 +617,11 @@ mod tests { fn value_texts() { assert_eq!(value_text(&json!(6.0)), "6"); assert_eq!(value_text(&json!(0.25)), "0.25"); + assert_eq!(value_text(&json!(1e300)), "1e+300"); + assert_eq!(value_text(&json!(-1.5e300)), "-1.5e+300"); + assert_eq!(value_text(&json!(1e-20)), "1e-20"); + assert_eq!(value_text(&json!(1e-300)), "1e-300"); + assert_eq!(value_text(&json!(0.0001)), "0.0001"); assert_eq!(value_text(&json!(true)), "TRUE"); assert_eq!(value_text(&json!({"error": "#DIV/0!"})), "#DIV/0!"); assert_eq!(value_text(&json!([[1.0, 2.0], [3.0, "x"]])), "1\t2\n3\tx");