2
byte b = 5;
int n = 33;
b<<n
b>>n

我知道如何计算它:如果这是左移,那么我们需要将数字乘以 2 到 n 次方,对于右移,我们必须将数字除以 2 到 n 次方。

如果 n 是很小的数字,我可以计算。如果 n 很大(比如这里是 33),有人可以解释我如何手动计算它,还是有其他方法?

4

4 回答 4

5

如果您的右操作数大于 31,那么您可以使用 along而不是int. 它的值介于 -2^63 和 2^63 - 1 之间。

并且当心>>,它不会做你直觉认为它会做的事情。它带有符号位!

例如,短片上写着:

1000 0101

右移 3 会得到完全违反直觉的结果:

1111 0001

代替:

0001 0001

如果您想要“真正的”右移,请>>>改用。

如果它比这更大,你必须使用BigInteger

final BigInteger b1 = new BigInteger("5");

BigIntegerhas.shiftLeft().shiftRight()方法(Java 的等价物<<>>>——注意三元组>——在整数原始类型上)。请注意,这些操作将返回一个 BigInteger的!所以,不要这样做:

b1.shiftLeft(33);

这不会影响b1. 做:

final BigInteger b2 = b1.shiftLeft(33);
于 2013-06-22T10:24:27.713 回答
3

使用long而不是byte.

long b = 5;
int n = 33;
System.out.println(b<<n);//n should be between 0 to 63
System.out.println(b>>n);//since you are using long,the operation returns long

如果左操作数很,右操作数应该在0 到 63之间

但如果左操作数不长,右操作数应该在0 到 31之间

如果您的右操作数可以大于 63,请使用BigInteger


笔记

仅允许整数类型(int、long、byte、short)作为移位运算符的操作数

于 2013-06-22T10:27:43.407 回答
2

好吧,基本上,您必须知道转移意味着什么。

如果你有一个5在内存中表示的数字0000101(位;字节有 8 位),左移(乘)看起来像这样:

00000101 << 1 = 00001010 = 10 (decimal) //shifting bits to the left
00000101 << 3 = 00101000 = 40 (decimal)

右移(除法):

00000101 >> 1 = 00000010 = 2 (decimal) //shifting bits to the right
00000101 >> 3 = 00000000 = 0 (decimal)

所以你可以使用循环和数学乘法/除法来做到这一点:

左移 - 乘:

byte b= 5;
long number= (byte)b;
int n= 33;
for (int i=0; i<n; i++) {
    number= number * 2;
}

b = (byte)number;

同样的道理,只是在 for 循环中除而不是乘。

于 2013-06-22T10:33:17.010 回答
0

手动,您仍然需要将其乘以 2^n 才能进行左移。猜猜看,要手动进行右移,您仍然需要除以 2^n 并将结果四舍五入。所以这里要详细手动做:

  1. 拿笔和纸。
  2. 写下你想换的号码。
  3. 将其转换为二进制基本表示。
  4. n在它后面添加零。
  5. 将数字转换回来。

或者,如果您不想使用二进制表示:

  1. 拿笔和纸。
  2. 写下你想换的号码。
  3. 手动计算 2^n。它像:1、2、4、8、16、32、64、128、256、512、1024、2048、4192、...
  4. 将数字乘以您刚刚使用此技术计算的数字。它被称为长乘法。
于 2013-06-22T10:39:30.443 回答