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:
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.
Ok, shortest solution without conditional is probably:
return (i|-i) >>> 31;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With