2
$\begingroup$

I need to avoid using an if statement that does a $\geq$ comparison, (I'm writing HLSL code for the xbox).

I need a function such that $f(x, y) = 0$ when $x < y$ and $f(x,y)=1$ when $x \geq y$.

(Shader programmers note, I can't use the step function as it's just as slow in this case).

Sorry if this question has cropped up before, I'm not sure what terms to use (so if someone can point me in the right direction, or improve my question tagging that'd be great).

  • 0
    @joriki: I don't agree, but am apparently in the minority here, so nevermind.2011-05-26

2 Answers 2

4

What about something like $f(x,y) = \dfrac{x-y}{2|x-y|} + \frac{1}{2}$? When $x, we get 0 and when $x>y$, we get 1. However, it depends on how the language interprets $0/0$ for the case when $x=y$. If it was something like java, you could just catch a divide by zero exception and have it return 1. Then this function would great.

Of course, this depends on having a form of the absolute value statement for the language that doesn't use an if statement - but many languages have very witty inbuilt functions for this case. Is this sort of what you were looking for?

  • 0
    @Joriki: whoops! I do math far more frequently than I program. Hopefully the OP is more aware of his programming environments than I am.2011-06-02
4

Your function is discontinuous. All mathematical operations usually implemented in programming languages, such as addition, multiplication, exponentiation etc. are continuous. Thus there cannot be a fully mathematical solution to your problem; every solution must involve some trick to deal with the discontinuity. Mixedmath's proposal does this by treating the case $x=y$ separately, e.g. by an exception.

If your language uses IEEE-like floats and allows bitwise float-to-int conversions and bit shifts, you could convert your float to an int bitwise and shift the sign bit to the least significant bit. In C, you could compute your function something like this:

double d = x - y; unsigned long f = 1 - ((* (unsigned long *) &d) >> 63); 

(assuming that both double and unsigned long are 64-bit types). In Java, it would be

long f = 1 - (Double.doubleToLongBits (x-y) >>> 63); 

(where you need the logical right-shift operator >>>, not the arithmetic one >>).

Note that any efficient implementation of the absolute value operation used in mixedmath's solution would also have to work on this level, by masking out the sign bit of IEEE-style floats; as mixedmath pointed out, a high-level implementation that compares against $0$ wouldn't avoid a comparison.

  • 0
    Ahh ok, think i understand now. Thanks for the extra answer.2011-05-26