java 负值 移位_Java:在负数上右移

操作员>>称为右移 ,将所有位右移指定的次数。 重要的是>>填充最左边的符号位(最高有效位MSB)到最左边的位后移。 这就是所谓的符号扩展 ,当你把它们移到正确的位置时,它可以保留负数的符号 。

下面是我的示意图,用一个例子来说明这是如何工作的(对于一个字节):

例:

i = -5 >> 3; shift bits right three time

5的补码forms是1111 1011

内存表示:

MSB +----+----+----+---+---+---+---+---+ | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | +----+----+----+---+---+---+---+---+ 7 6 5 4 3 2 1 0 ^ This seventh, the left most bit is SIGN bit

下面是,如何>>工作? 当你做-5 >> 3

this 3 bits are shifted out and loss MSB (___________) +----+----+----+---+---+---+---+---+ | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | +----+----+----+---+---+---+---+---+ | \ \ | ------------| ----------| | | | ▼ ▼ ▼ +----+----+----+---+---+---+---+---+ | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | +----+----+----+---+---+---+---+---+ (______________) The sign is propagated

注意:最左边的三位是一个,因为每个移位符号位被保留,每一位都是正确的。 我写了这个符号被传播,因为所有这三个位都是因为符号(而不是数据)。

另外由于三权右移最多的三位都是亏损的。

右两个箭头之间的位从前面的位-5中暴露出来。

我认为如果我也为正数编写一个例子,这将是一件好事。 下一个例子是5 >> 3 ,五个是一个字节是0000 0101

this 3 bits are shifted out and loss MSB (___________) +----+----+----+---+---+---+---+---+ | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | +----+----+----+---+---+---+---+---+ | \ \ | ------------| ----------| | | | ▼ ▼ ▼ +----+----+----+---+---+---+---+---+ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +----+----+----+---+---+---+---+---+ (______________) The sign is propagated

再次看到我写的符号传播 ,所以最左边的三个零是由于签名位。

所以这就是运营商>> 签名右移做,保留左操作数的符号。

[你的答案]

在你的代码中,你使用>>运算符将-15右移31次,所以你的最右边的31位被释放,结果都是实际为-1位1 。

你是否注意到这样-1 >> n等于不是一个声明。

我相信如果一个人做i = -1 >> n它应该优化到i = -1的Java编译器,但这是不同的问题

接下来,在Java中知道更多的右移运算符是有用的>>>称为无符号右移 。 它在逻辑上工作并且从每次换class操作的左侧填充零。 因此,在每次右移时,如果对正负数都使用无符号右移>>>运算符,则总是会在最左边的位置得到一个零位。

例:

i = -5 >>> 3; Unsigned shift bits right three time

下面是我的图演示如何expression式-5 >>> 3作品?

this 3 bits are shifted out and loss MSB (___________) +----+----+----+---+---+---+---+---+ | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | +----+----+----+---+---+---+---+---+ | \ \ | ------------| ----------| | | | ▼ ▼ ▼ +----+----+----+---+---+---+---+---+ | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | +----+----+----+---+---+---+---+---+ (______________) These zeros are inserted

你可以注意到:这一次我不写符号位传播,但实际上>>>运算符插入零。 因此>>>不会保留符号,而是做逻辑右移。

据我所知,无符号右移在VDU(graphics编程)中是有用的,尽pipe我没有使用它,但是在过去的某些地方读过它。

我build议你阅读这个: >>>和>>之间的区别 : >>是算术右移, >>>是逻辑右移。

编辑 :

一些有趣的关于无符号右移运算符>>>运算符。

无符号的右移运算符>>>产生一个纯粹的值,它的左操作数右移0 0扩展右操作数指定的位数。

像>>和<< ,运算符>>>运算符也不会抛出exception。

无符号右移运算符的每个操作数的types必须是整型数据types,否则会发生编译时错误。

>>>操作符可以对其操作数执行types转换; 与算术二元运算符不同,每个操作数都是独立转换的。 如果操作数的types是byte,short或char,则在计算运算符的值之前,将该操作数转换为int。

无符号右移运算符生成的值的types是其左操作数的types。 LEFT_OPERAND >>> RHIGT_OPERAND

如果左操作数的转换types是int,则只有右操作数值的五个最低有效位用作移位距离。 ( 即2 5 = 32位= int中的位数 )

所以移动距离在0到31之间。

这里, r >>> s产生的值与下面的一样:

s==0 ? r : (r >> s) & ~(-1<

如果左操作数的types很长,那么只有右操作数值的6个最低有效位被用作移位距离( 即2 5 = 64位=长位数 )

这里, r >>> s产生的值与下面相同:

s==0 ? r : (r >> s) & ~(-1<

一个有趣的参考: [第4章] 4.7移位运算符

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值