Я хочу реализовать f(int x) { return x == 0 ? 0 : 1; }
в Java.
В C я просто "return !!x;
", но !
не работает так, как в Java. Есть ли способ сделать это без условностей? Без чего-то дрянного, как развернутая версия
int ret = 0;
for (int i = 0; i < 32; i++) {
ret |= ((x & (1 << i)) >>> i);
}
или
try {
return x/x;
} catch (ArithmeticException e) {
return 0;
}
)
EDIT:
Итак, я сделал microbenchmark трех разных решений:
- мое решение для возврата x/x,
- очевидное решение x == 0? 0: 1 и
- Решение Ed Staub: (x | -x) → > 31.
Тайминги для случайных входов int (весь диапазон int) были:
1. 0.268716
2. 0.324449
3. 0.347852
Да, мое глупое решение x/x было быстрее благодаря довольно внушительному запасу. Не удивительно, если учесть, что в нем очень мало 0, и в подавляющем большинстве случаев выполняется быстрый путь.
Тайминги для более интересного случая, когда 50% входов 0:
1. 1.256533
2. 0.321485
3. 0.348999
Наивное решение x==0?0:1
было быстрее примерно на 5%, чем умное (на моей машине). Завтра я попытаюсь сделать разборку, чтобы выяснить, почему.
EDIT2: Итак, разбор для условной версии (за исключением бухгалтерского учета):
testl rsi,rsi
setnz rax
movzbl rax,rax
Разборка для (x | -x) → > 31:
movl rax,rsi
negl rax
orl rax,rsi
sarl rax,#31
Я не думаю, что что-то еще нужно сказать.