开发者

Is this possible to achieve using some sort of bit magic?

If have a function which returns a negative number, 0, or a positive number. What I want instead is return -1 in case of a positive number, 0 in ca开发者_Go百科se of 0 and +1 in case of a positive number.

Can I achieve something like this using some sort of bit-fiddling or do I have to do ordinary comparisons?


You could use a test of sign bit, but aside from bringing assumptions about the integer size you'd still need to test for zero.

Instead I suggest the following "magic":

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

Clean, explicit, portable and indeed very fast on most compilers. The only plausible code-level optimization I'd suggest would be test for zero value first (or second) if you know this case to be is more frequent.


If you're looking for a neat expression:

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


You definitely could achieve this by playing with the bits, but if you can't envision how to do it, you can't expect that people working with your code later will be able to read it.

Just use an if-else statement, your code will be simpler and you can move onto more important programming (or playing on SO :)).


If you're willing to assume 2s complement, that right-shift of a signed type is arithmetic (neither of those assumptions is portable, but they do hold for many common platforms), and you're really dead set on being too clever by half:

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

A bunch assumptions for something that's fairly cryptic, and no guarantee that it's actually faster on any given platform.


I'm going to assume that (a) you meant -1 for a negative number and (b) the range was -254 to +254.

Negative or positive could be evaluated by looking at only one bit, but to test for zero you're going to need to inspect all the bits to make sure they are all zero, which kind of defeats the purpose of using a bit manipulation "shortcut".


If I understood the question correctly:

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;
};

It's not "compressed" to show the logic.


If the integers are represented using 2's complement, then you need only look at the most significant bit. If it's a 1, then it's negative, otherwise it's positive or zero.

See also: 2's Complement


Don't look for bizarre bit magic, just divide the number by its magnitude and you'll get the sign.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜