rotchess_core/
floating_drift.rs1#[macro_export]
2macro_rules! floating_drift_adjust {
12 ($($x:expr),+ $(,)?) => {{
13 const EPSILON: f32 = 1e-4;
14
15 fn round_if_close_to_integer(val: f32) -> f32 {
17 if (val - val.round()).abs() < EPSILON {
18 val.round()
19 } else {
20 val
21 }
22 }
23
24 ($(round_if_close_to_integer($x as f32)),+)
26 }};
27}
28
29pub use floating_drift_adjust;
30
31#[cfg(test)]
32mod tests {
33 #[test]
34 fn values_close_to_integers() {
35 let result = floating_drift_adjust!(1.000001, 2.999999, 3.0);
36 assert_eq!(result, (1.0, 3.0, 3.0));
37 }
38
39 #[test]
40 fn values_not_close_to_integers() {
41 let result = floating_drift_adjust!(1.5, 2.7, 3.2);
42 assert_eq!(result, (1.5, 2.7, 3.2));
43 }
44
45 #[test]
46 fn mixed_close_and_not_close() {
47 let result = floating_drift_adjust!(1.000001, 2.5, 3.999999);
48 assert_eq!(result, (1.0, 2.5, 4.0));
49 }
50
51 #[test]
52 fn mixed_integer_and_float_types() {
53 let result = floating_drift_adjust!(1, 2.000001, 3.999999);
54 assert_eq!(result, (1.0, 2.0, 4.0));
55 }
56
57 #[test]
58 fn single_value_close_to_integer() {
59 let result = floating_drift_adjust!(4.000001);
60 assert_eq!(result, (4.0));
61 }
62
63 #[test]
64 fn single_value_not_close_to_integer() {
65 let result = floating_drift_adjust!(4.5);
66 assert_eq!(result, (4.5));
67 }
68
69 #[test]
70 fn many_values_all_close() {
71 let result = floating_drift_adjust!(1.0, 2.000001, 3.999999, 4.0, 5.000001);
72 assert_eq!(result, (1.0, 2.0, 4.0, 4.0, 5.0));
73 }
74
75 #[test]
76 fn many_values_mixed() {
77 let result = floating_drift_adjust!(1.000001, 2.5, 3.0, 4.7, 5.999999);
78 assert_eq!(result, (1.0, 2.5, 3.0, 4.7, 6.0));
79 }
80
81 #[test]
82 fn negative_values() {
83 let result = floating_drift_adjust!(-1.000001, -2.999999);
84 assert_eq!(result, (-1.0, -3.0));
85 }
86
87 #[test]
88 fn zero_values() {
89 let result = floating_drift_adjust!(0.000001, -0.000001);
90 assert_eq!(result, (0.0, 0.0));
91 }
92
93 #[test]
94 fn mixed_negative_and_positive() {
95 let result = floating_drift_adjust!(-1.000001, 2.5, 3.999999);
96 assert_eq!(result, (-1.0, 2.5, 4.0));
97 }
98}