得到一个有符号数的符号位

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)会得到10

关于方法23

// 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))