无符号位移和有符号位移

转载:https://blog.youkuaiyun.com/BushQiang/article/details/79394211

           https://blog.youkuaiyun.com/qq_26129689/article/details/50640293

无符号位移(>>>、<<<)和有符号位移(>>、<<)

关于数的移位,特别需要注意:

1、正数,三码(源码、反码、补码)相同,所以无论左移还是右移都是补0.(左移则表示放大2的N次方,右移表示缩小2的N次方)

2、负数的补码就需要注意,左移在右边补0,右移需要在左边补1

     有一个很有趣的误区是,认为符号位保持不变,仅仅移动数据位,这是不对的,因为无论数据位还是符号位,都是二进制,在整体大迁移的过程中,符号位也是要跟随潮流的。只不过,为了保证右移后,和原来的符号数一样,因此,负数在右移时左边补

计算机表示数字正负不是用+ -加减号来表示,而是用最高位数字来表示,0表示正,1表示负

1.有符号右移>>(若正数,高位补0,负数,高位补1)

正数:例如4>>2

首先写出4的二进制数,因为是正数所以最高位为0,也就是第一个

 0000 0100

右移两位得到(高位补0)

 0000  0001

结果为:1,右移n位也就是4/(2^n)

 

负数:例如-4>>2(高位补1)

首先写出-4的二进制数源码,因为是负数所以最高位为1   (负数的源码是负数的绝对值)

1000 0100

然后写出-4反码:保证符号位不变,其余位置取反

1111 1011(反码)

最后写出-4的补码:在反码的基础上加1

1111 1100(补码)

右移2位: 在高位补1

1111 1111

根据补码写出原码才是我们所求的结果, 保留符号位,然后减1取反       (或按位取反再加上1

1111 1110(减1的结果)

1000 0001(取反的结果)

结果为:-1

 

2:无符号右移>>>(不论正负,高位均补0)  注意:无符号,所以都是当正数操作的

正数:例如4>>>2

与4>>2的运算相同,结果也为1

负数:例如-4>>>2

首先写出-4的二进制数,因为是负数所以最高位为1

1000 0100

然后写出-4补码:保证符号位不变,其余位置取反加1(从右往左遇到第一个1,然后剩下的全部取反就是了)

1111 1100(补码)

右移2位: 在高位补0

0011 1111

结果为:63

 

### 位移运算符概述 位移运算符是一种针对二进制数据的操作工具,在多种编程语言中都有广泛应用。它主要包括左移(`<<`)、有符号右移(`>>`)无符号右移(`>>>`),分别用于不同的场景。 #### 左移运算符 (`<<`) 左移运算符会将操作数的每一位向左移动指定的数量,右侧补零。这种操作通常用来快速实现数值乘以 \(2^n\) 的效果[^3]。例如: ```java int a = 5; // 二进制表示为 00000101 a = a << 1; // 结果为 10, 即十进制下的 10 (二进制 00001010) ``` 上述代码展示了如何通过左移一位来使变量 `a` 的值翻倍。 #### 右移运算符 (`>>`) 无符号右移运算符 (`>>>`) 右移运算符则相反,它是将操作数的每一位向右移动指定数量的位置。对于带符号整型来说,高位会被填充上原最高有效位的内容;而对于无符号右移,则无论何种情况都会用零填补左侧空缺位置[^1]。这使得它可以作为除法的一种替代形式,即每次执行一次右移相当于被\(2^n\)相除。 以下是 Java 中的一个例子展示这两种不同类型的右移行为差异: ```java public class ShiftExample { public static void main(String[] args){ int numSigned = -8; System.out.println(numSigned >> 1); // 输出 -4 int numUnsigned = -8; System.out.println(numUnsigned >>> 1); // 输出 2147483644 } } ``` 在这个实例里可以看到,当处理负数时,“>>”保留了原始符号而“>>>”忽略了原有的符号信息并填入了正号前缀。 #### 实际应用场景案例分享 考虑这样一个需求——计算物体自由下落到地面后的连续弹跳高度变化过程模拟程序[^4]: ```java public class FreeFallSimulation{ public static void main(String []args){ int initialHeight = 10000;// 初始掉落高度设定为一万米单位厘米计 for(int count=1 ;count<=10 ;count++){ initialHeight >>=1 ; System.out.printf("第%d次反弹后当前的高度:%d cm\n",count ,initialHeight); } } } ``` 此段代码利用了简单的循环结构配合每轮迭代都将现有高度做半减处理直至完成预定次数为止的功能设计思路。 ### 总结 综上所述,无论是为了提升性能还是简化某些特定算法表达式,掌握好位移运算符都是非常有益处的一项技能。它们不仅能够帮助我们更高效地管理内存资源而且还能增强解决问题的能力范围。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值