Re: Float/Double compare

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Ian,

On Sat, 2007-06-30 at 15:25 -0400, Ian Rogers wrote:
> public static int compare(float x, float y)
> {
>    int ix = floatAsIntBits(x);
>    int iy = floatAsIntBits(y);
>    if (ix == iy) return 0;
>    if (isNaN(x)) return 1;
>    if (isNaN(y)) return -1;
>    int ix_sign = ix>>31;
>    int iy_sign = iy>>31;
>    if (ix_sign == iy_sign) {
>      return x > y ? 1 : -1;
>    } else {
>      return ix_sign - iy_sign;
>    }
> }

I am not really comfortable with writing this as is since unless the
compiler is smart you will do a multiple isNaN() and floatToIntBits()
calls even if not necessary. Could we try to do something smarter and
factor some of this out like:

// First check for NaNs
if (x != x || y != y)
  {
    int ix = floatToIntBits(x);
    int iy = floatToIntBits(y);
    if (ix == iy)
      return 0;
    if (x != x)
      return 1;
    if (y != y)
      return -1;
  }
else
  {
    // Normal cases, or positive/negative zeros
    if (x > y)
      return 1;
    if (y > x)
      return -1;

    // Either equal or positive/negative zeros
    if (x == 0 && y == 0)
      {
        int ix = floatToIntBits(x);
        int iy = floatToIntBits(y);
        int ix_sign = ix >> 31;
        int iy_sign = iy >> 31;
        return ix_sign - iy_sign;
      }

    return 0;
  }

But maybe I am not giving the compiler/jit enough credit for actually
producing such an optimized version in the first place. And this isn't
actually the same as your code since I moved the NaN checks first again.
The above assumes the NaN test (x != x) is relatively cheap since NaN is
a canonical value is java. That might be a wrong assumption. You might
be able to do something more clever with the actual ordering of floats
according to > (since if any argument is NaN or both are zero it
evaluates to false) or with the ordering of floatToIntBits, but my head
was spinning trying to keep all the corner cases right (this calls for
expanding the Mauve Float.compareTo() test).

> There may be a bug I can't see in this code :-)

Same with mine (I admit to not even having tried to compile it...)

Cheers,

Mark



[Index of Archives]     [Linux Kernel]     [Linux Cryptography]     [Fedora]     [Fedora Directory]     [Red Hat Development]

  Powered by Linux