如何判断32位int是否适合16位短路
仅使用:
! ~ & ^ | + <>
我需要找出一个带符号的32位整数是否可以表示为16位,二进制补码整数。
我的第一个想法是分离MSB 16位和LSB 16位,然后使用掩码和最后16位,所以如果它不为零,它将无法表示,然后使用该数字来检查MSB位。
我需要编写的函数示例是:fitsInShort(33000)= 0(无法表示)和fitsInShort(-32768)= 1(可以表示)
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)) );
编辑:奥利是对的。 我不知何故以为他们被允许了。 这是最后一次尝试,并附有解释:
我们需要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;
如果32位数字在[-32768,+ 32767]范围内,则17个msbs将全部相同。
这是一个糟糕的方式来判断一个3位数字是仅使用您的操作是全部还是全部零(我假设您不允许条件控制结构,因为它们需要隐式逻辑运算):
int allOnes3(int x) { return ((x >> 0) & (x >> 1) & (x >> 2)) & 1; } int allTheSame3(int x) { return allOnes3(x) | allOnes3(~x); }
我会告诉你扩展/改进这个概念。
这是一个没有强制转换,if语句和仅使用您要求的运算符的解决方案:
#define fitsInShort(x) !(((((x) & 0xffff8000) >> 15) + 1) & 0x1fffe)
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; }
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位都已设置,因此它可以适合(else部分),否则它不适合(if条件)。