diff --git a/crates/render/src/units.rs b/crates/render/src/units.rs index 61f616ec..f3d429c6 100644 --- a/crates/render/src/units.rs +++ b/crates/render/src/units.rs @@ -102,7 +102,8 @@ fn feet_inches(neg: bool, ft: i64, inch_plain: &str, inch_m: &str, inch_zero: bo let mode = zin & 3; let show_ft = ft != 0 || mode == 1 || mode == 2; let show_in = !inch_zero || mode == 1 || mode == 3 || (ft == 0 && !show_ft); - let sign = if neg { "-" } else { "" }; + // A negative value that rounds to zero prints without a sign. + let sign = if neg && (ft != 0 || !inch_zero) { "-" } else { "" }; let mut p = String::from(sign); let mut m = String::from(sign); if show_ft { @@ -282,6 +283,39 @@ mod tests { assert_eq!(format_linear(0.4, &f(5, 2, 0)).0, "1/2"); } + #[test] + fn negative_values_rounding_to_zero_have_no_sign() { + for unit in 1..=5 { + for decimals in [0, 2, 4] { + for zin in [0, 1] { + for v in [-1e-9, -0.0] { + let (p, m) = format_linear(v, &f(unit, decimals, zin)); + assert!(!p.starts_with('-') || unit == 1 && v != 0.0, "unit {unit} decimals {decimals} zin {zin}: {p}"); + assert!(!m.starts_with('-') || unit == 1 && v != 0.0, "unit {unit} decimals {decimals} zin {zin}: {m}"); + } + } + } + } + // DIMRND rounding a small negative value to zero, in every unit. + for unit in 1..=5 { + let mut c = f(unit, 4, 0); + c.round = 0.25; + let (p, m) = format_linear(-0.1, &c); + assert!(!p.starts_with('-') && !m.starts_with('-'), "unit {unit} with DIMRND: {p} / {m}"); + } + assert_eq!(format_linear(-1e-9, &f(4, 4, 0)).0, "0\""); + assert_eq!(format_linear(-1e-9, &f(3, 4, 0)).0, "0.0000\""); + // Scientific keeps the sign: the mantissa of a tiny negative value is not zero. + assert_eq!(format_linear(-1e-9, &f(1, 2, 0)).0, "-1.00E-09"); + // The shared feet/inch joiner never signs an all-zero result. + assert_eq!(feet_inches(true, 0, "0", "0", true, 0).0, "0\""); + assert_eq!(feet_inches(true, 0, "0", "0", true, 1).0, "0'-0\""); + // Genuinely negative values keep the sign. + assert_eq!(format_linear(-18.5, &f(4, 4, 0)).0, "-1'-6 1/2\""); + assert_eq!(format_linear(-18.5, &f(3, 2, 0)).0, "-1'-6.50\""); + assert_eq!(format_linear(-24.0, &f(4, 4, 0)).0, "-2'"); + } + #[test] fn angles() { assert_eq!(format_angle(std::f64::consts::FRAC_PI_4, 0, 0, 0), "45°");