Strange comparison behavior

Hi everyone,
I'm a student working on a small Rust project with a lookup table. I wrote a simple linear search function that, given a xq and a monotonic axis array, returns the interval indices (i0,i1) where xq lies. I also wanted to return (i,i) if xq is exactly equal to a breakpoint.

Here's a simplified version of my function:

fn index_search<T: FloatLike, const N: usize>(xq: &T, axis: &[T;N])-> (usize,usize){
    if *xq<=axis[0] {
        return (0,0);
    }
    if *xq>=axis[N-1] {
        return (N-1, N-1);
    }
    for i in 0..N-1 {
        let x0 = axis[i];
        let x1 = axis[i+1];
        if *xq==x0 {
            return (i, i);
        }
        if *xq>=x0 && *xq<=x1 {
            return (i, i+1);
        }
    }
    return (0,0)
}

The strange thing is: when I search for a value that exactly matches a breakpoint, it doesn't return (i,i) as expected.
Interestingly, if I change the interval check from >=/<= to >/<, the function works as intended.
I don“t fully understand why. Logically, if xq==x0, the first branch should return (i,i) before even reaching the interval check, right?

I know it might be a silly question, I'm still learning Rust but I'd love to understand why the original version behave differently and whether this is something about floating-point comparisons or Rust control flow.

Thanks a lot in advance for any explanations!

You test whether xq == x0, but not if xq == x1, before continuing with your xq >= x0 && xq <= x1 test. If xq == x1, you will thus return (i, i + 1) instead of (i + 1, i + 1) as intended. Making the upper bound check non-inclusive (i.e. xq >= x0 && xq < x1 instead of xq >= x0 && xq <= x1) does indeed fix this (x1 becomes x0 in the next iteration), as you already noticed.