From 72a9e4456e4664266d81321115d901cd98445003 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Wed, 21 Oct 2026 03:34:30 +0000 Subject: [PATCH] Fix scientific number format for subnormal values Found while testing crates/model/src/numfmt.rs:204-211 (sci) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/model/src/numfmt.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/model/src/numfmt.rs b/crates/model/src/numfmt.rs index c3cf1713..da2e2315 100644 --- a/crates/model/src/numfmt.rs +++ b/crates/model/src/numfmt.rs @@ -204,7 +204,12 @@ fn sci(toks: &[Tok], v: f64, sep: char, dec: char) -> Option { let (mut m, mut exp) = (0.0, 0i32); if v != 0.0 { exp = v.log10().floor() as i32; - m = v / 10f64.powi(exp); + m = if exp < -300 { + // 10^exp underflows for subnormals; scale in two steps. + v * 1e300 / 10f64.powi(exp + 300) + } else { + v / 10f64.powi(exp) + }; if !m.is_finite() { m = 0.0; exp = 0; @@ -286,6 +291,12 @@ mod tests { const RUB: &str = r#"_-* #\ ##0\ "₽"_-;\-* #\ ##0\ "₽"_-;_-* "-"??\ "₽"_-;_-@_-"#; + #[test] + fn scientific_subnormal() { + assert_eq!(format("0.00E+00", 5e-324, None), "4.94E-324"); + assert_eq!(format("0.00E+00", f64::MIN_POSITIVE, None), "2.23E-308"); + } + #[test] fn russian_accounting_roubles() { assert_eq!(format(RUB, 800_000.0, Some("ru-RU")), "800\u{a0}000 ₽");