java的三种移位运算符>>、>>>和左移——其中特殊的负数

Java中,<<、>>、>>>都是在数字的二进制中进行的 。

老样子,直接先上代码(服不服,运行看):

    public static void main(String[] args) {

        System.out.println("1>>4    运算的结果是 :" + ((1) >> 4));
        System.out.println("1>>>4   运算的结果是 :" + ((1) >>> 4));
        System.out.println("1<<4    运算的结果是 :" + ((1) << 4));
        System.out.println("");
        System.out.println("-1>>4   运算的结果是 :" + ((-1) >> 4));
        System.out.println("-1>>>4  运算的结果是 :" + ((-1) >>> 4));
        System.out.println("-1<<4   运算的结果是 :" + ((-1) << 4));
        System.out.println("");
        System.out.println("16>>2   运算的结果是 :" + ((16) >> 2));
        System.out.println("16>>>2  运算的结果是 :" + ((16) >>> 2));
        System.out.println("16<<2   运算的结果是 :" + ((16) << 2));
        System.out.println("");
        System.out.println("-16>>2  运算的结果是 :" + ((-16) >> 2));
        System.out.println("-16>>>2 运算的结果是 :" + ((-16) >>> 2));
        System.out.println("-16<<2  运算的结果是 :" + ((-16) << 2));
        System.out.println("");
        System.out.println("33>>5   运算的结果是 :" + ((33) >> 5));
        System.out.println("33>>>5  运算的结果是 :" + ((33) >>> 5));
        System.out.println("33<<5   运算的结果是 :" + ((33) << 5));
        System.out.println("");
        System.out.println("-33>>5  运算的结果是 :" + ((-33) >> 5));
        System.out.println("-33>>>5 运算的结果是 :" + ((-33) >>> 5));
        System.out.println("-33<<5  运算的结果是 :" + ((-33) << 5));
        
    }
1>>4    运算的结果是 :0
1>>>4   运算的结果是 :0
1<<4    运算的结果是 :16

-1>>4   运算的结果是 :-1
-1>>>4  运算的结果是 :268435455
-1<<4   运算的结果是 :-16

16>>2   运算的结果是 :4
16>>>2  运算的结果是 :4
16<<2   运算的结果是 :64

-16>>2  运算的结果是 :-4
-16>>>2 运算的结果是 :1073741820
-16<<2  运算的结果是 :-64

33>>5   运算的结果是 :1
33>>>5  运算的结果是 :1
33<<5   运算的结果是 :1056

-33>>5  运算的结果是 :-2
-33>>>5 运算的结果是 :134217726
-33<<5  运算的结果是 :-1056

 

这里我解释其中一个例子:

 

由于,在计算机中,负数采用二进制的补码方式存储(不明白自己上网查一下),重要的话说三遍:

所以,针对负数的左、右移都是由补码开始移动的!!

所以,针对负数的左、右移都是由补码开始移动的!!

所以,针对负数的左、右移都是由补码开始移动的!!

最后,对移动后的补码再取补码,才得到原码。然后转化为10进制,即为移动后我们要的数值。

 

补充知识点:

10进制转为二进制得到的是原码,将原码按位取反得到的是反码,反码加1得到补码补码的补码得到的是原码

二进制的最高位是符号位,0表示正,1表示负。

 

 

-1的原码:    10000000 00000000 00000000 00000000

-1的补码:    11111111 11111111 11111111 11111111


-1>>4:        
            00001111 11111111 11111111 11111111(-1的补码先“右移4位”)
            00001000 00000000 00000000 00000001(再取补,这样才是原码)= -1
            说明:最前面的那个“1”表示符号。(即左数第五个数字)

-1>>>4:        
            00001111 11111111 11111111 11111111(-1的补码先“无符号右移4位”)
            00001111 11111111 11111111 11111111(再取补,这样才是原码)= 268435455
            说明:无符号位右移,由于无符号位右移的规定结果必须是正数,所以原符号位的“1”被自动转换为对应的数值,不再代表符号)。且,正数的补码是本身,所以不变。


          
-1<<4:        
            11111111 11111111 11111111 11110000(-1的补码左移4位)
            10000000 00000000 00000000 00010000(再取补,这样才是原码)= -16
            说明:最前面的那个“1”表示符号。(即左数第一个数字)

 

以上,

不明白的地方可以评论,我会耐心解答。

本人原创,觉得有用的点个赞哈,以鼓励我继续为大家趟路、继续原创。

 

 

<think>嗯,用户这次聚焦在位移运算符比较运算符的用法上,还特别提到优先级问题。从引用内容看,用户可能正在学习Java或类似语言的位运算,且对运算符优先级很敏感——引用[3]详细列出了优先级表,引用[1]强调了优先级对计算准确性的影响,尤其金融计算这种容错率低的场景。用户提问有些碎片化("位移运算符大于等于运算符用法编程"),需要拆解核心需求:1)位移运算符具体用法(尤其无符号右移>>>的特殊性)2)比较运算符的实践要点3)这两类运算符在优先级上的关联。引用[2][3]恰好覆盖了这些:引用[2]用2<<3的例子生动说明位移运算符的高效性,引用[3]的优先级表显示比较运算符优先级(第10级)高于位移运算符(第9级)——这意味着表达式里先算比较再算位移。编程示例的选择很重要。用户可能更关注数值运算场景(引用[4]提到进制转换),所以用计算校验码权限判断两个例子:前者展示位移运算的数值处理能力(用户提到金融计算),后者利用位掩码+比较运算符实现状态判断(用户身份验证常用)。优先级示例特意选了a>>>1==b这种易混淆的写法,呼应引用[1]强调的加括号最佳实践。安全问题需要提醒。用户引用的资料提到移位可能导致意外值(如引用[3]的5>>>34位),补充了数据类型限制(Java中int只能移31位)补位规则,避免用户掉坑。</think> 以下是关于位移运算符(`<<`、`>>`、`>>>`)大于等于运算符(`>=`)的用法说明及编程示例: --- ### **一、位移运算符用法** 1. **左移运算符 `<<`** - 格式:`value << n` - 作用:将二进制位向左移动 `n` 位,低位补 `0`。 - **等效操作**:$value \times 2^n$ - 示例: ```java int a = 8; // 二进制: 1000 int b = a << 2; // 左移2位 → 100000 (十进制: 32) ``` 2. **带符号右移 `>>`** - 格式:`value >> n` - 作用:向右移动 `n` 位,**高位补符号位**(正数补 `0`,负数补 `1`)。 - **等效操作**:$value \div 2^n$(向下取整) - 示例: ```java int c = -16; // 二进制: 1111111111110000 (32位) int d = c >> 2; // 右移2位 → 1111111111111100 (十进制: -4) ``` 3. **无符号右移 `>>>`** - 格式:`value >>> n` - 作用:向右移动 `n` 位,**高位强制补 `0`**(无论正负)。 - **注意**:对负数操作会得到正数结果。 - 示例: ```java int e = -16; // 二进制: 1111111111110000 int f = e >>> 2; // 无符号右移 → 0011111111111100 (十进制: 1073741820) ``` --- ### **二、大于等于运算符 `>=` 用法** - **功能**:比较两个值,若左侧值 ≥ 右侧值,返回 `true`;否则返回 `false`。 - **支持类型**:数值类型(`int`, `float` 等)可比较对象(如 `Comparable` 类型)。 - **优先级**:高于逻辑运算符(`&&`, `||`),低于算术运算符(`+`, `*` 等)[^3]。 - 示例: ```java int x = 10, y = 5; boolean result1 = (x >= y); // true(10 ≥ 5) boolean result2 = (y >= x); // false(5 < 10) ``` --- ### **三、综合应用示例** ```java // 1. 用左移实现快速乘法 int base = 7; int fastMultiply = base << 3; // 7 * 8 = 56 // 2. 用右移判断奇偶性 int num = 15; boolean isEven = ((num >> 1) << 1) == num; // 右移后左移,若与原值相等则为偶数 // 3. 位移与比较结合:校验权限范围 int userPermission = 0b1101; // 二进制权限标志 int requiredPermission = 0b1001; boolean hasAccess = (userPermission >>> 1) >= requiredPermission; // 校验高阶权限 ``` --- ### **四、关键注意事项** 1. **位移运算符限制**: - 只支持整数类型(`byte`, `int`, `long`)[^2]。 - 移动位数超过数据类型位数时(如 `int` 移 32 位以上),结果不可预测[^3]。 2. **优先级陷阱**: ```java int a = 10; boolean flag = a >>> 1 == 5; // 错误!等价于 (a>>>1)==5 boolean safeFlag = (a >>> 1) == 5; // 正确:显式加括号 ``` 3. **无符号右移的特殊性**: - 对负数操作可能导致意外的大正数(如上述 `-16 >>> 2`)。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值