这有可能实现使用某种魔法吗?

时间:2010-12-07 23:11:52

标签: c bit-manipulation

如果有一个返回负数,0或正数的函数。我想要的是在正数的情况下返回-1,在0的情况下返回0,在正数的情况下返回+1。

我可以使用某种小小的方法来实现这样的事情,还是我必须进行普通的比较?

8 个答案:

答案 0 :(得分:5)

您可以使用符号位测试,但除了假设整数大小之外,您还需要测试零。

相反,我建议以下“魔术”:

if (myvalue > 0)
   return 1;
else if (myvalue < 0)
   return -1;
else
   return 0;

大多数编译器都干净,明确,可移植,而且速度非常快。我建议的唯一合理的代码级优化,如果您知道这种情况更频繁,则首先(或第二)测试零值。

答案 1 :(得分:3)

如果你正在寻找一个整洁的表达方式:

return (val > 0) - (val < 0);

答案 2 :(得分:2)

你绝对可以通过玩这些位来实现这一目标,但如果你无法想象如何做到这一点,你就不能指望以后使用你的代码的人能够阅读它。

只需使用if-else语句,您的代码就会更简单,您可以转到更重要的编程(或者在SO上播放:)。

答案 3 :(得分:2)

如果你愿意假设2s补码,那么签名类型的右移是算术的(这些假设都不是可移植的,但它们确实适用于许多常见的平台),你真的死定了太聪明了一半:

int number;
const int shift = sizeof number * CHAR_BIT - 1;
return (number >> shift) - (-number >> shift);

对于某些相当神秘的东西的一系列假设,并不能保证它在任何给定平台上实际上更快。

答案 4 :(得分:1)

我将假设(a)你的意思是-1表示负数,(b)范围是-254到+254。

可以通过仅查看一个位来评估负或正,但是为了测试零,您将需要检查所有位以确保它们都为零,哪种类型的使用失败了操纵“捷径”。

答案 5 :(得分:1)

如果使用2的补码表示整数,那么您只需要查看最重要的位。如果它是1,则它是负数,否则它是正数或零。

另请参阅:2's Complement

答案 6 :(得分:1)

如果我正确理解了这个问题:

static inline int sign(unsigned int n){
    int sign_bit = n >> (sizeof(int)*CHAR_BIT - 1); //sign_bit = n<0 will also do
    int is_zero = !n;
    return 1 - is_zero - sign_bit * 2;
};

显示逻辑并不是“压缩”的。

答案 7 :(得分:0)

不要寻找奇怪的魔法,只需将数字除以它的大小就可以得到符号。