const_soft_float/soft_f32/
cmp.rs

1use crate::soft_f32::SoftF32;
2use core::cmp::Ordering;
3
4type F = SoftF32;
5
6type FInt = u32;
7type FSignedInt = i32;
8
9const UNORDERED: Option<Ordering> = None;
10const EQUAL: Option<Ordering> = Some(Ordering::Equal);
11const GREATER: Option<Ordering> = Some(Ordering::Greater);
12const LESS: Option<Ordering> = Some(Ordering::Less);
13
14pub(crate) const fn cmp(a: F, b: F) -> Option<Ordering> {
15    let one: FInt = 1;
16    let zero: FInt = 0;
17    let szero: FSignedInt = 0;
18
19    let sign_bit = F::SIGN_MASK as FInt;
20    let abs_mask = sign_bit - one;
21    let exponent_mask = F::EXPONENT_MASK;
22    let inf_rep = exponent_mask;
23
24    let a_rep = a.repr();
25    let b_rep = b.repr();
26    let a_abs = a_rep & abs_mask;
27    let b_abs = b_rep & abs_mask;
28
29    // If either a or b is NaN, they are unordered.
30    if a_abs > inf_rep || b_abs > inf_rep {
31        return UNORDERED;
32    }
33
34    // If a and b are both zeros, they are equal.
35    if a_abs | b_abs == zero {
36        return EQUAL;
37    }
38
39    let a_srep = a.signed_repr();
40    let b_srep = b.signed_repr();
41
42    // If at least one of a and b is positive, we get the same result comparing
43    // a and b as signed integers as we would with a fp_ting-point compare.
44    if a_srep & b_srep >= szero {
45        if a_srep < b_srep {
46            LESS
47        } else if a_srep == b_srep {
48            EQUAL
49        } else {
50            GREATER
51        }
52        // Otherwise, both are negative, so we need to flip the sense of the
53        // comparison to get the correct result.  (This assumes a twos- or ones-
54        // complement integer representation; if integers are represented in a
55        // sign-magnitude representation, then this flip is incorrect).
56    } else if a_srep > b_srep {
57        LESS
58    } else if a_srep == b_srep {
59        EQUAL
60    } else {
61        GREATER
62    }
63}