Row*_*awn 6 c bit-manipulation bitwise-operators
使用按位运算符,我想加法和减法,我如何检查有符号整数是否为正(特别是,不是负数而不是零)?我相信这个问题的答案非常简单,但它并没有找到我.
如果你真的想要一个"严格肯定"的谓词int n而不使用条件(假设2的补码):
-n将有符号(顶部)位设置,如果n是严格为正,而在所有其他情况下,明确除 n == INT_MIN ;~n如果n严格为正,则将设置符号位,或0,并在所有其他情况下清除,包括 n == INT_MIN ;-n & ~n如果n严格为正,则将设置符号位,并在所有其他情况下清除.应用无符号移位将其转换为0/1答案:
int strictly_positive = (unsigned)(-n & ~n) >> ((sizeof(int) * CHAR_BIT) - 1);
Run Code Online (Sandbox Code Playgroud)
编辑:正如caf在评论中指出的那样,-n导致溢出时n == INT_MIN(仍然假设2的补码).在这种情况下,C标准允许程序失败(例如,您可以使用带-ftrapv选项的GCC为已签名的溢出启用陷阱).转换n为无符号修复了问题(无符号算术不会导致溢出).所以改进是:
unsigned u = (unsigned)n;
int strictly_positive = (-u & ~u) >> ((sizeof(int) * CHAR_BIT) - 1);
Run Code Online (Sandbox Code Playgroud)