問題を解決するかなり簡潔な式を次に示します。
return ((x < 0 ^ y) & x!=0) << 31 | (x!=0) << 31 >> 31 & 0x7fffffff & x | x==0x80000000 ;
これは、32 ビットの 2 の補数整数に対して機能します。ここで、x は入力であり、y は 1 または 0 のいずれかです。1 は x の反対の符号を返すことを意味し、0 は x と同じ符号を返すことを意味します。
関数 f() でのその式のより長いバージョンを次に示します。確認するためにいくつかのテストケースを追加しました。
#include <limits.h>
#include <stdio.h>
int bitsm1 = 31;
int rightbits = 0x7fffffff;
int f (x, y) {
int sign_x = x < 0;
int signtemp = sign_x ^ y;
int notzero = x!=0;
int v = notzero << bitsm1;
v = v >> bitsm1;
v = v & rightbits;
int b = v & x;
int c = (signtemp & notzero) << bitsm1;
int z = c | b;
int res = z | (x==INT_MIN);
return res;
}
int main () {
printf("%d\n", f(0,0)); // 0
printf("%d\n", f(0,1)); // 0
printf("%d\n", f(1,0)); // +
printf("%d\n", f(1,1)); // -
printf("%d\n", f(-1,0)); // -
printf("%d\n", f(-1,1)); // +
printf("%d\n", f(INT_MAX,0)); // +
printf("%d\n", f(INT_MAX,1)); // -
printf("%d\n", f(INT_MIN,0)); // -
printf("%d\n", f(INT_MIN,1)); // +
return 0;
}