From 1428174159818979c9dc86c2ec5fb5a55bcced3b Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Sat, 24 Oct 2026 07:49:49 +0200 Subject: [PATCH] Fall back to decimal for huge architectural/fractional distances (#1762) Found while testing crates/engine/src/units.rs:27-31 and 44-46 Co-authored-by: Claude Haiku 5.5 --- crates/engine/src/units.rs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/crates/engine/src/units.rs b/crates/engine/src/units.rs index 5575273c..236ec5af 100644 --- a/crates/engine/src/units.rs +++ b/crates/engine/src/units.rs @@ -2,6 +2,10 @@ use std::f64::consts::PI; +/// Largest scaled value (below `i64::MAX`) that the integer feet/inch splitting handles; larger +/// distances fall back to decimal. +const I64_SAFE_MAX: f64 = 9.0e18; + /// Format a distance per LUNITS (1 scientific, 2 decimal, 3 engineering, 4 architectural, /// 5 fractional) and LUPREC. pub fn format_distance(v: f64, lunits: i64, luprec: i64) -> String { @@ -25,7 +29,11 @@ pub fn format_distance(v: f64, lunits: i64, luprec: i64) -> String { let neg = v < 0.0; let a = v.abs(); let denom = 1i64 << prec.min(8); - let total = (a * denom as f64).round() as i64; + let scaled = (a * denom as f64).round(); + if scaled >= I64_SAFE_MAX { + return format!("{:.*}", prec, v); + } + let total = scaled as i64; let ft = total / (12 * denom); let rem = total - ft * 12 * denom; let inch = rem / denom; @@ -42,7 +50,11 @@ pub fn format_distance(v: f64, lunits: i64, luprec: i64) -> String { let neg = v < 0.0; let a = v.abs(); let denom = 1i64 << prec.min(8); - let total = (a * denom as f64).round() as i64; + let scaled = (a * denom as f64).round(); + if scaled >= I64_SAFE_MAX { + return format!("{:.*}", prec, v); + } + let total = scaled as i64; let whole = total / denom; let frac = total % denom; let fs = if frac == 0 { @@ -335,6 +347,17 @@ pub const DEG: f64 = PI / 180.0; mod tests { use super::*; + #[test] + fn huge_architectural_and_fractional_distances_do_not_saturate() { + for lunits in [4, 5] { + for v in [1e30, -1e30] { + assert_eq!(format_distance(v, lunits, 4), format!("{:.4}", v), "lunits {lunits}"); + } + } + assert_eq!(format_distance(1e15, 5, 4), "1000000000000000"); + assert_eq!(format_distance(12.5, 4, 4), "1'-0 1/2\""); + } + #[test] fn directions_show_from_angbase_in_the_angdir_sense() { let north_clockwise = AngleSettings { aunits: 0, angbase: 90f64.to_radians(), clockwise: true };