1use std::cmp::Ordering;
11
12pub fn cmp_int_float(a: i64, b: f64) -> Option<Ordering> {
16 if b.is_nan() {
17 return None;
18 }
19 if b >= 9_223_372_036_854_775_808.0 {
22 return Some(Ordering::Less); }
24 if b < -9_223_372_036_854_775_808.0 {
25 return Some(Ordering::Greater); }
27 let bt = b.trunc();
29 let bi = bt as i64;
30 match a.cmp(&bi) {
31 Ordering::Equal if b > bt => Some(Ordering::Less), Ordering::Equal if b < bt => Some(Ordering::Greater), ord => Some(ord), }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[test]
42 fn exact_above_2_pow_53() {
43 assert_eq!(
45 cmp_int_float(9_007_199_254_740_993, 9_007_199_254_740_992.0),
46 Some(Ordering::Greater)
47 );
48 assert_eq!(
50 cmp_int_float(9_007_199_254_740_992, 9_007_199_254_740_992.0),
51 Some(Ordering::Equal)
52 );
53 }
54
55 #[test]
56 fn fractions_and_small_values() {
57 assert_eq!(cmp_int_float(1, 1.5), Some(Ordering::Less));
58 assert_eq!(cmp_int_float(2, 1.5), Some(Ordering::Greater));
59 assert_eq!(cmp_int_float(-2, -1.5), Some(Ordering::Less));
60 assert_eq!(cmp_int_float(-2, -2.5), Some(Ordering::Greater));
61 assert_eq!(cmp_int_float(0, 0.0), Some(Ordering::Equal));
62 }
63
64 #[test]
65 fn out_of_range_and_nan() {
66 assert_eq!(cmp_int_float(5, 1e300), Some(Ordering::Less));
67 assert_eq!(cmp_int_float(5, -1e300), Some(Ordering::Greater));
68 assert_eq!(
69 cmp_int_float(i64::MAX, 9_223_372_036_854_775_808.0),
70 Some(Ordering::Less)
71 );
72 assert_eq!(
73 cmp_int_float(i64::MIN, -9_223_372_036_854_775_808.0),
74 Some(Ordering::Equal)
75 );
76 assert_eq!(cmp_int_float(1, f64::NAN), None);
77 }
78}