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 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-24 01:49:49 -04:00
committed by GitHub
co-authored by Claude Haiku 5.5
parent f686a595e6
commit 1428174159
+25 -2
View File
@@ -2,6 +2,10 @@
use std::f64::consts::PI; 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, /// Format a distance per LUNITS (1 scientific, 2 decimal, 3 engineering, 4 architectural,
/// 5 fractional) and LUPREC. /// 5 fractional) and LUPREC.
pub fn format_distance(v: f64, lunits: i64, luprec: i64) -> String { 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 neg = v < 0.0;
let a = v.abs(); let a = v.abs();
let denom = 1i64 << prec.min(8); 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 ft = total / (12 * denom);
let rem = total - ft * 12 * denom; let rem = total - ft * 12 * denom;
let inch = rem / 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 neg = v < 0.0;
let a = v.abs(); let a = v.abs();
let denom = 1i64 << prec.min(8); 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 whole = total / denom;
let frac = total % denom; let frac = total % denom;
let fs = if frac == 0 { let fs = if frac == 0 {
@@ -335,6 +347,17 @@ pub const DEG: f64 = PI / 180.0;
mod tests { mod tests {
use super::*; 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] #[test]
fn directions_show_from_angbase_in_the_angdir_sense() { fn directions_show_from_angbase_in_the_angdir_sense() {
let north_clockwise = AngleSettings { aunits: 0, angbase: 90f64.to_radians(), clockwise: true }; let north_clockwise = AngleSettings { aunits: 0, angbase: 90f64.to_radians(), clockwise: true };