2017-03-14 125 views
0

我在长时间编写FitsBits时遇到了一些问题,所以我使用了它,并找到了适合测试程序的解决方案,但我无法弄清楚这意味着什么。按位操作:FitsBits

问题描述:

fitsBits - 返回1,如果x能够被表示为n比特, 二的补码整数。
= N < = 32个
实例:

fitsBits(5,3)= 0,fitsBits(-4,3)= 1个
法律OPS:! 〜&^| + < < >> 最大OPS:15

一个合适的解决方案是:

int fitsBits(int x, int n) 
{ 
int move; 
move = 32 +(~n+1); 
return !(x^((x<<move)>>move)); 
} 

但我不知道

(X ^((X < <移动) >> move))

意味着什么。

我真的需要一些帮助.Thx!

回答

1

此问题与Bitwise operations and shifts重复,用户要求了解相同的代码。不幸的是我没有名声来标记它。

重申Code-Apprentice's答案和AnT's,基于你找到了解决办法,更说明了一些修改我自己

move = 32 +(~n+1); 

这实际上是32间(和大小的不同n的最大值,在这个问题中的整数)和n。

了解为什么看着两个补码有符号整数。在此格式在转换一个无符号的整数,例如在原来的实例中,5(0101)到-5经由反转比特和添加一种,

~5 + 1 = -5 

~(0101) + 1 = 1011 

通知如何1011不能配合到3个比特,并且仍然是负数(在2的补负数必须以1)

所以

move = 32 +(~n+1); 

实际上

move = 32 - n; 

是最后一行实际上是一个线

!(x^((x<<move)>>move)); 

一些想法,以便让其分解。

invert the truthiness of 
    (x xor a number) 
     where the number is x first shifted left then right amount move 
      and move is the difference between n and 32. 

让我们再次使用5和3的例子。我们知道移动应该是32-3,所以移动是29.

但是为什么左右移动的数量相同?通常,当你看到一些人在代码中这样做时,他们试图“清零”一个数字。在这种情况下,作者没有这样做,但是符号扩展。看看下面

例如:

given 0000 0000 0000 0000 0000 0000 0000 0101 = 5 
5 << 29 = 1010 0000 0000 0000 0000 0000 0000 0000 = -1610612736 
-1610612736 >> 29 = 1111 1111 1111 1111 1111 1111 1111 1101 = -3 

笔者使用RSHIFT的执行层面怪癖,如果该号码开始作为一个签名,它保持它的标志和符号填充为数字其余的移动。

注意填充符号的方式(5 >> 29)< < 29不会导致相同的数字,因为当我们将5移动到32位有符号数的末尾时,它从1开始,因此变为自己签名。

下一行是要简单得多

(x^number) 

将是0,如果x ==数量,因为0 XOR 1 = 1,和1个XOR 1 = 0,和0 XOR 0 = 0。因此,通过该逻辑,当我们颠倒x的感实性,我们正在检查是否

x == (sign shifted x) 

如果5是,比方说,8而不是(1000),我们将简单地失去了最后一个数字(1),我们会发现,

!(8^0) == false. 

如果我们选择使用一个实际工作的数字(比如说3),因为3 = 011,而向右移动29将导致第一位为0,当来回移动时我们将保留3的值,所以我们会发现

!(3^3) == true; 

总结功能真的只是做以下

given int x and int n, 
check if x == (x shifted left then sign shifted right by (size of int in bits - n)) 
+1

谢谢!你真的帮助了我。 – HumbertZhang