如何判断32位int是否适合16位短路

时间:2011-09-07 16:44:22

标签: c integer bit-manipulation

仅使用:

! ~ & ^ | + << >>

我需要找出一个带符号的32位整数是否可以表示为16位,二进制补码整数。

我的第一个想法是将MSB 16位和LSB 16位分开,然后使用掩码和最后16位,所以如果它不为零,它将无法表示,然后使用该数字来检查MSB位。

我需要写的函数的一个例子是:fitsInShort(33000)= 0(无法表示)和fitsInShort(-32768)= 1(可以表示)

5 个答案:

答案 0 :(得分:8)

如果32位数字在[-32768,+ 32767]范围内,则17个msbs将全部相同。

这是一种蹩脚的方式来判断一个3位数是全是1还是全零只使用你的操作(我假设你不允许条件控制结构,因为它们需要隐式逻辑运算):

int allOnes3(int x)
{
    return ((x >> 0) & (x >> 1) & (x >> 2)) & 1;
}

int allTheSame3(int x)
{
    return allOnes3(x) | allOnes3(~x);
}

我会让你扩展/改进这个概念。

答案 1 :(得分:8)

bool fits16(int x)
{
    short y = x;
    return y == x;
}

开个玩笑:)这是真正的答案,假设int是32位,short是16位和2的补码represantation:

编辑:请参阅上一次编辑以获得正确答案!

bool fits16(int x)
{
    /* Mask out the least significant word */
    int y = x & 0xffff0000;
    if (x & 0x00008000) {
        return y == 0xffff0000;
    } else {
        return y == 0;
    }
}

如果没有if语句我应该这样做:

return (
    !(!(x & 0xffff0000) || !(x & 0x00008000)) ||
    !((x & 0xffff0000) || (x & 0x00008000))
);

编辑:Oli是对的。我不知何故以为他们被允许了。这是最后一次尝试,并附有解释:

我们需要x的17个最高有效位是全部或全部为零。所以让我们首先掩盖其他位:

int a = x & 0xffff8000; // we need a to be either 0xffff8000 or 0x00000000
int b = a + 0x00008000; // if a == 0xffff8000 then b is now 0x00000000
                        // if a == 0x00000000 then b is now 0x00008000
                        // in any other case b has a different value
int c = b & 0xffff7fff; // all zeroes if it fits, something else if it doesn't
return c;

或者更简洁:

return ((x & 0xffff8000) + 0x8000) & 0xffff7fff;

答案 2 :(得分:3)

这是一个没有强制转换,if语句并只使用你要求的运算符的解决方案:

#define fitsInShort(x) !(((((x) & 0xffff8000) >> 15) + 1) & 0x1fffe)

答案 3 :(得分:0)

if (!(integer_32 & 0x8000000))
{
   /* if +ve number */
  if (integer_32 & 0xffff8000)
    /* cannot fit */
  else 
    /* can fit */
}
else if (integer_32 & 0x80000000)
{
  /* if -ve number */
  if ( ~((integer_32 & 0xffff8000) | 0x00007fff))
    /* cannot fit */
  else
    /* can fit */
}

首先if首先通过检查已签名位来检查+ ve编号。如果+ ve,则它检查第15位到第31位是否为0,如果为0,则它​​不能适合short,否则它可以。

如果第15位到第31位都已设置,则负数为范围(2的补码方法表示)。

因此第二个if是-ve数,然后第15到31位被屏蔽掉,剩下的低位(0到14)被设置。如果这是0xffffffff那么只有一个补码将是0,这表示第15到31位都已设置,因此它可以适合(其他部分),否则它不适合(if条件) )。

答案 4 :(得分:0)

short fitsInShort(int x)
{
    int positiveShortRange = (int) ((short) 0xffff / (short) 2);
    int negativeShortRange = (int) ((short) 0xffff / (short) 2) + 1;

    if(x > negativeShortRange && x < positiveShortRange)
        return (short) x;
    else
        return (short) 0;
}