C语言仅用指定位运算实现符号判断函数求助
问题分析与修正
原代码的错误点
- 变量含义颠倒:
positive = ((x >> 31) & 1):对于有符号整数,负数右移31位会得到全1(即-1),与1相与结果为1;正数和0右移31位为0,结果为0。这个变量实际是负数标志,而非正数。negative = !((x >> 31) & -1):负数右移31位是-1,与-1相与仍为-1,取反后为0;正数右移31位是0,与-1相与为0,取反后为1。这个变量实际是正数标志,而非负数。
- 返回逻辑错误:
positive | !zero | ~negative的组合完全不符合需求,例如x为正数时,!zero是1,~negative是~1=-2,三者按位或后结果为-1,与预期的1完全相反。
正确实现方案
利用有符号整数右移的特性(负数右移31位得到-1,正数和0右移31位得到0),结合指定操作符构造结果:
int sign(int x) { int neg = x >> 31; // x<0时为-1,x>=0时为0 int pos = (!(!x)) & !(neg); // x>0时为1,x<=0时为0 return neg | pos; }
逻辑验证
- 当x<0:
neg=-1,!(!x)=1(x非0),!(neg)=!(-1)=0,所以pos=0,最终-1 | 0 = -1,符合要求。 - 当x>0:
neg=0,!(!x)=1,!(neg)=!0=1,所以pos=1,最终0 | 1 = 1,符合要求。 - 当x=0:
neg=0,!(!x)=!1=0,所以pos=0,最终0 | 0 = 0,符合要求。
更简洁的写法
可以把逻辑合并成一行,减少临时变量:
int sign(int x) { return (x >> 31) | ((!(!x)) & !(x >> 31)); }
内容的提问来源于stack exchange,提问作者Chandler Dotson
相关产品推荐
相关产品推荐

