如何判断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条件)。