Немного более запутанно, но есть это:
(~((x >> 31) & 1) + 1) | (((~x + 1) >> 31) & 1)
Это должно позаботиться о неоднозначности того, заполнит ли сдвиг 1 или 0
Для разбивки, в любом месте у нас есть эта конструкция:
(z >> 31) & 1
Результатом будет 1, если отрицательно, и 0 в противном случае.
В любом месте у нас есть:
(~z + 1)
Получаем отрицательное число (-z)
Таким образом, первая половина выдаст результат 0xFFFFFFFF (-1), если x будет отрицательным, а вторая половина выдаст 0x00000001 (1), если x будет положительным. Побитовое или объединение их вместе приведет к получению 0x00000000 (0), если ни один из них не равен true.