commit 385571a5b32d00e7edf60fe59983effedb8e481f
parent 53c97b7ea841fbf827ca0c5c2d03399e75c28114
Author: William Casarin <jb55@jb55.com>
Date: Mon, 23 Feb 2026 17:48:29 -0800
protoverse: fix f32→f64 precision noise in serialized numbers
Round to 4 decimal places and strip trailing zeros to prevent
values like -0.20000000298023224 from appearing in serialized
S-expression output.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat:
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/crates/protoverse/src/serializer.rs b/crates/protoverse/src/serializer.rs
@@ -17,7 +17,13 @@ fn format_number(n: f64) -> String {
if n == n.floor() && n.abs() < i64::MAX as f64 {
format!("{}", n as i64)
} else {
- format!("{}", n)
+ // Round to 4 decimal places to avoid f32→f64 noise
+ // (e.g. -0.20000000298023224 → -0.2)
+ let rounded = (n * 10000.0).round() / 10000.0;
+ let s = format!("{:.4}", rounded);
+ let s = s.trim_end_matches('0');
+ let s = s.trim_end_matches('.');
+ s.to_string()
}
}
@@ -117,4 +123,21 @@ mod tests {
assert!(output.contains("(name \"Test\")"));
assert!(output.contains("(width 10)"));
}
+
+ #[test]
+ fn test_format_number_strips_float_noise() {
+ // Integers
+ assert_eq!(format_number(10.0), "10");
+ assert_eq!(format_number(-3.0), "-3");
+ assert_eq!(format_number(0.0), "0");
+
+ // Clean decimals
+ assert_eq!(format_number(1.5), "1.5");
+ assert_eq!(format_number(-0.2), "-0.2");
+
+ // f32→f64 noise: -0.2f32 as f64 == -0.20000000298023224
+ assert_eq!(format_number(-0.2_f32 as f64), "-0.2");
+ assert_eq!(format_number(0.5_f32 as f64), "0.5");
+ assert_eq!(format_number(1.125_f32 as f64), "1.125");
+ }
}