f(int x) { return x == 0 ? 0 : 1; } in Java without conditionals

Viewed 11454

I want to implement f(int x) { return x == 0 ? 0 : 1; } in Java.

In C, I'd just "return !!x;", but ! doesn't work like that in Java. Is there some way to do it without conditionals? Without something cheesy like an unrolled version of

int ret = 0;
for (int i = 0; i < 32; i++) {
    ret |= ((x & (1 << i)) >>> i);
}

or

try {
   return x/x;
} catch (ArithmeticException e) {
   return 0;
}

)

EDIT:

So, I did a microbenchmark of three different solutions:

  1. my return x/x catch solution,
  2. the obvious x==0?0:1 solution, and
  3. Ed Staub's solution: (x|-x) >>> 31.

The timings for random int inputs (the whole int range) were:

1. 0.268716  
2. 0.324449  
3. 0.347852  

Yes, my stupid x/x solution was faster by a pretty hefty margin. Not very surprising when you consider that there are very few 0's in it, and in the vast majority of cases the fast path is taken.

The timings for the more interesting case where 50% of inputs are 0:

1. 1.256533  
2. 0.321485  
3. 0.348999  

The naive x==0?0:1 solution was faster by about 5% than the clever one (on my machine). I'll try to do some disassembly tomorrow to find out why.

EDIT2: Ok, so the disassembly for the conditional version is (excluding book-keeping):

testl rsi,rsi
setnz rax
movzbl rax,rax

The disassembly for (x|-x)>>>31 is:

movl rax,rsi
negl rax
orl rax,rsi
sarl rax,#31

I don't think anything else needs to be said.

8 Answers
Related