Compute the sign of an integer描述了如何得到一个有符号数的符号位:
int v; // we want to find the sign of v
int sign; // the result goes here
// CHAR_BIT is the number of bits per byte (normally 8).
sign = -(v < 0); // if v < 0 then -1, else 0.
// or, to avoid branching on CPUs with flag registers (IA32):
sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));
// or, for one less instruction (but not portable):
sign = v >> (sizeof(int) * CHAR_BIT - 1);
关于方法1
:
sign = -(v < 0); // if v < 0 then -1, else 0.
参考C
规范6.5.8:6
:
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.92) The result has type int.
因此(v < 0)
会得到1
或0
。
关于方法2
和3
:
// or, to avoid branching on CPUs with flag registers (IA32):
sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));
// or, for one less instruction (but not portable):
sign = v >> (sizeof(int) * CHAR_BIT - 1);
参考stackoverflow
这篇帖子。因为有符号数类型中的负数右移是C
规范中未定义行为,取决与具体体系结构的实现,因此需要先把它转化成无符号数进行右移操作:
((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1))