admin管理员组

文章数量:1031905

位移运算

前言:

最近刚开始看《码出高效-Java开发手册》,看到位移运算这里发现了一个以前没有关注过的点,也就是博客标题,百思不解,经过一番搜索才真的了解了位移运算的实质。

我们知道位移符号一共有三种,左移<<、右移>>、无符号右移>>>

左移<<和右移>>

在左移<<和右移>>两种运算中,符号位均参与移动,除负数往右移动,高位补1之外,其他情况均在空位补0。

无符号右移>>>

当向右移动时,正负数高位均补0,正数不断向右移动的最小值是0,而负数不断向右移动的最小值是1。无符号意即藐视符号位,符号位失去特权,必须像其他平常的数字位一起向右移动,高位直接补0,根本不关心是正数还是负数。

先上代码看看:

代码语言:javascript代码运行次数:0运行复制
public static void main(String[] args) {
    int num = -32,num1 = -64,num2 = 32;
    int a = num >> 33;
    int b = num >>> 31;
    int c = num1 >>> 64;
    int d = num1 >>> 63;
    int h = num1 >>> 65;
    int e = num2 >> 33;
    int f = num2 >>> 31;

    System.out.println("-32 >> 33:" + a);
    System.out.println("-32 >>> 31:" + b);
    System.out.println("-64 >>> 64:" + c);
    System.out.println("-64 >>> 63:" + d);
    System.out.println("-64 >>> 65:" + h);
    System.out.println("32 >>> 33:" + e);
    System.out.println("32 >>>> 31:" + f);
}

运算结果:

这里我们可以重点看一下-64的无符号右移

第一个问题:-64 >>> 64的结果是-64,不是说负数不断地无符号向右移动的最小值是1吗? 第二个问题:-64 >>> 63的结果是1,按照上面的说法似乎没有疑问,但是为什么呢??? 第三个问题:-64 >>> 65的结果为什么那么大?

在实际编程中,位移运算仅作用于整型(32位)和长整型(64位)数上,假如在整型数上移动的位数是字长(同一时间处理二进制的位数)的整数倍,无论是否带符号以及移动方向,均为本身(这里解决了第一个问题)。

因为移动的位数是一个mod64的结果,即:对一个64位数进行无符号右移操作时,实际的位移为 位移值%64 也就是 >>>64 = >>>0,那么,一个64位数一次最大无符号右移值为63位,由于负数的第一位为-1,则-1XXX(63位X)>>>63 = 000(63个0)1。(这里解决了第二个问题)

而对于32位的数再说,无符号右移位数为 位移值%32 ,像short这种类型的数,在做位移之前,会先转为int类型,然后再进行转换。

那么,第三个问题的答案自行思考吧

这里还是举例补充说明一下吧,毕竟我也理解了很久

代码语言:javascript代码运行次数:0运行复制
System.out.println("-16无符号右移2位:"+(-16>>>2));
//-16无符号右移2位:1073741820

这个是为什么?

首先一定要知道 无符号右移运算符>>> 只是对32位和64位的值有意义,这个在前面也说了 例如: -16的无符号右移2位应该这样算才对----------------------取32位长度的16的二进制补码加1 16二进制:00000000 00000000 00000000 00010000 补码+1后:11111111 11111111 11111111 11110000 右移两位高位补零:00111111 11111111 11111111 11111100 这个二进制对应的值就是1073741820

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-04-07,如有侵权请联系 cloudcommunity@tencent 删除int编程博客二进制开发

位移运算

前言:

最近刚开始看《码出高效-Java开发手册》,看到位移运算这里发现了一个以前没有关注过的点,也就是博客标题,百思不解,经过一番搜索才真的了解了位移运算的实质。

我们知道位移符号一共有三种,左移<<、右移>>、无符号右移>>>

左移<<和右移>>

在左移<<和右移>>两种运算中,符号位均参与移动,除负数往右移动,高位补1之外,其他情况均在空位补0。

无符号右移>>>

当向右移动时,正负数高位均补0,正数不断向右移动的最小值是0,而负数不断向右移动的最小值是1。无符号意即藐视符号位,符号位失去特权,必须像其他平常的数字位一起向右移动,高位直接补0,根本不关心是正数还是负数。

先上代码看看:

代码语言:javascript代码运行次数:0运行复制
public static void main(String[] args) {
    int num = -32,num1 = -64,num2 = 32;
    int a = num >> 33;
    int b = num >>> 31;
    int c = num1 >>> 64;
    int d = num1 >>> 63;
    int h = num1 >>> 65;
    int e = num2 >> 33;
    int f = num2 >>> 31;

    System.out.println("-32 >> 33:" + a);
    System.out.println("-32 >>> 31:" + b);
    System.out.println("-64 >>> 64:" + c);
    System.out.println("-64 >>> 63:" + d);
    System.out.println("-64 >>> 65:" + h);
    System.out.println("32 >>> 33:" + e);
    System.out.println("32 >>>> 31:" + f);
}

运算结果:

这里我们可以重点看一下-64的无符号右移

第一个问题:-64 >>> 64的结果是-64,不是说负数不断地无符号向右移动的最小值是1吗? 第二个问题:-64 >>> 63的结果是1,按照上面的说法似乎没有疑问,但是为什么呢??? 第三个问题:-64 >>> 65的结果为什么那么大?

在实际编程中,位移运算仅作用于整型(32位)和长整型(64位)数上,假如在整型数上移动的位数是字长(同一时间处理二进制的位数)的整数倍,无论是否带符号以及移动方向,均为本身(这里解决了第一个问题)。

因为移动的位数是一个mod64的结果,即:对一个64位数进行无符号右移操作时,实际的位移为 位移值%64 也就是 >>>64 = >>>0,那么,一个64位数一次最大无符号右移值为63位,由于负数的第一位为-1,则-1XXX(63位X)>>>63 = 000(63个0)1。(这里解决了第二个问题)

而对于32位的数再说,无符号右移位数为 位移值%32 ,像short这种类型的数,在做位移之前,会先转为int类型,然后再进行转换。

那么,第三个问题的答案自行思考吧

这里还是举例补充说明一下吧,毕竟我也理解了很久

代码语言:javascript代码运行次数:0运行复制
System.out.println("-16无符号右移2位:"+(-16>>>2));
//-16无符号右移2位:1073741820

这个是为什么?

首先一定要知道 无符号右移运算符>>> 只是对32位和64位的值有意义,这个在前面也说了 例如: -16的无符号右移2位应该这样算才对----------------------取32位长度的16的二进制补码加1 16二进制:00000000 00000000 00000000 00010000 补码+1后:11111111 11111111 11111111 11110000 右移两位高位补零:00111111 11111111 11111111 11111100 这个二进制对应的值就是1073741820

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-04-07,如有侵权请联系 cloudcommunity@tencent 删除int编程博客二进制开发

本文标签: 位移运算