INT_MIN
からまでの int の範囲全体を処理する、C でのこの比較的短いソリューションを提案しますINT_MAX
。
符号付き整数が 2 の補数として実装されることを期待し、符号付きオーバーフロー (未定義の動作になることが知られている) による悪影響がないことを期待しています。
#include <stdio.h>
#include <limits.h>
int isGreater(int x, int y)
{
// "x > y" is equivalent to "!(x <= y)",
// which is equivalent to "!(y >= x)",
// which is equivalent to "!(y - x >= 0)".
int nx = ~x + 1; // nx = -x (in 2's complement integer math)
int r = y + nx; // r = y - x (ultimately, we're interested in the sign of r,
// whether r is negative or not)
nx ^= nx & x; // nx contains correct sign of -x (correct for x=INT_MIN too)
// r has the wrong sign if there's been an overflow in r = y + nx.
// It (the r's sign) has to be inverted in that case.
// An overflow occurs when the addends (-x and y) have the same sign
// (both are negative or both are non-negative) and their sum's (r's) sign
// is the opposite of the addends' sign.
r ^= ~(nx ^ y) & (nx ^ r); // correcting the sign of r = y - x
r >>= (CHAR_BIT * sizeof(int) - 1); // shifting by a compile-time constant
return r & 1; // return the sign of y - x
}
int testDataSigned[] =
{
INT_MIN,
INT_MIN + 1,
-1,
0,
1,
INT_MAX - 1,
INT_MAX
};
int main(void)
{
int i, j;
for (j = 0; j < sizeof(testDataSigned)/sizeof(testDataSigned[0]); j++)
for (i = 0; i < sizeof(testDataSigned)/sizeof(testDataSigned[0]); i++)
printf("%d %s %d\n",
testDataSigned[j],
">\0<=" + 2*!isGreater(testDataSigned[j], testDataSigned[i]),
testDataSigned[i]);
return 0;
}
出力:
-2147483648 <= -2147483648
-2147483648 <= -2147483647
-2147483648 <= -1
-2147483648 <= 0
-2147483648 <= 1
-2147483648 <= 2147483646
-2147483648 <= 2147483647
-2147483647 > -2147483648
-2147483647 <= -2147483647
-2147483647 <= -1
-2147483647 <= 0
-2147483647 <= 1
-2147483647 <= 2147483646
-2147483647 <= 2147483647
-1 > -2147483648
-1 > -2147483647
-1 <= -1
-1 <= 0
-1 <= 1
-1 <= 2147483646
-1 <= 2147483647
0 > -2147483648
0 > -2147483647
0 > -1
0 <= 0
0 <= 1
0 <= 2147483646
0 <= 2147483647
1 > -2147483648
1 > -2147483647
1 > -1
1 > 0
1 <= 1
1 <= 2147483646
1 <= 2147483647
2147483646 > -2147483648
2147483646 > -2147483647
2147483646 > -1
2147483646 > 0
2147483646 > 1
2147483646 <= 2147483646
2147483646 <= 2147483647
2147483647 > -2147483648
2147483647 > -2147483647
2147483647 > -1
2147483647 > 0
2147483647 > 1
2147483647 > 2147483646
2147483647 <= 2147483647