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

Vis*_*hal 7 c integer bit-manipulation

仅使用:

! ~ & ^ | + << >>
Run Code Online (Sandbox Code Playgroud)

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

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

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

Oli*_*rth 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);
}
Run Code Online (Sandbox Code Playgroud)

我会告诉你扩展/改进这个概念.


cyc*_*130 8

bool fits16(int x)
{
    short y = x;
    return y == x;
}
Run Code Online (Sandbox Code Playgroud)

开个玩笑:)这是真正的答案,假设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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

return (
    !(!(x & 0xffff0000) || !(x & 0x00008000)) ||
    !((x & 0xffff0000) || (x & 0x00008000))
);
Run Code Online (Sandbox Code Playgroud)

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

我们需要17个最重要的位x是全部或全部为零.所以让我们从屏蔽其他位开始:

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;
Run Code Online (Sandbox Code Playgroud)

或者更简洁:

return ((x & 0xffff8000) + 0x8000) & 0xffff7fff;
Run Code Online (Sandbox Code Playgroud)

  • OP没有提到逻辑运算符(`&&`,`||`). (2认同)