# Step function for greaterthan

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).

-
There is no mathematical question here: you have already defined the function you want. The question of how you tell this to some programming language does not belong here. Hence I vote as off-topic. – Rasmus May 26 '11 at 7:38
Sorry, i don't understand. The reason for this question is programming related, but the question (what mathematical function is 0 when x < y and 1 when x >= y) is a mathematical one. (isn't it?) – George Duckett May 26 '11 at 7:41
@Rasmus: I disagree, and vote to keep open. The question is not about how to tell something to a programming language, but about expressing this function explicitly without distinguishing cases. – joriki May 26 '11 at 7:42
My interest is piqued - why can't you use an if statement, and what possible implementation of the step function causes it to be slower than mixedmath's solution, which uses a division and exception handling? – Chris Taylor May 26 '11 at 8:54
@Chris. In HLSL (High Level Shader Language) any conditional (in a loop especially) is very bad, as the graphics card can't do so much in parallel. (it has to wait for the longest running branch to finish... or something). Not sure why, but on the xbox, adding an if statement to conditionally break out of a loop early was vastly more expensive than completing the loop in all cases. Same with step (which is an intrinsic function of HLSL). My knowledge doesnt extend to the "why" unfortunately. See my question here – George Duckett May 26 '11 at 9:23

What about something like $f(x,y) = \dfrac{x-y}{2|x-y|} + \frac{1}{2}$? When $x<y$, 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?

-
A floating-point divide-by-zero won't cause an exception in Java; in the present case, $0/0$ would result in a NaN, which would make the whole result come out as NaN. – joriki May 26 '11 at 7:59
That's exactly what i was after, thanks. – George Duckett May 26 '11 at 8:08
@Joriki: whoops! I do math far more frequently than I program. Hopefully the OP is more aware of his programming environments than I am. – mixedmath Jun 2 '11 at 6:52

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.

-
I understand your first paragraph, thanks for the insight. Not quite following the second part though. Are you giving an example of how to do an absolute value function? I don't understand how that helps deal with the case x = y. – George Duckett May 26 '11 at 8:37
@George: No, I was trying to specify the function you want to compute, but I got it the wrong way round -- I've corrected it now. – joriki May 26 '11 at 8:41
@George: I just realized there was another problem; the cast as I had it would have caused a numeric conversion, not a bitwise conversion; you'd need to do it with a pointer cast as in the corrected version. – joriki May 26 '11 at 8:49
Ahh ok, think i understand now. Thanks for the extra answer. – George Duckett May 26 '11 at 9:18