仅使用:
! ~ & ^ | + << >>
我需要找出一个带符号的32位整数是否可以表示为16位,二进制补码整数。
我的第一个想法是将MSB 16位和LSB 16位分开,然后使用掩码和最后16位,所以如果它不为零,它将无法表示,然后使用该数字来检查MSB位。
我需要写的函数的一个例子是:fitsInShort(33000)= 0(无法表示)和fitsInShort(-32768)= 1(可以表示)
答案 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;
}