详解java中如何进行位移操作[二进制级别]

二进制是啥啊?

咳咳,在这里咱先引入一下百度百科关于二进制的内容,先对他有个大概理解:

  二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”。
  二进制数(binaries)是逢2进位的进位制,0、1是基本算符 ;计算机运算基础采用二进制,电脑的基础是二进制。在早期设计的常用的进制主要是十进制(因为我们有十个手指,所以十进制是比较合理的选择,用手指可以表示十个数字,0的概念直到很久以后才出现,所以是1-10而不是0-9)。电子计算机出现以后,使用电子管来表示十种状态过于复杂,所以所有的电子计算机中只有两种基本的状态,开和关。也就是说,电子管的两种状态决定了以电子管为基础的电子计算机采用二进制来表示数字和数据。常用的进制还有8进制和16进制,在电脑科学中,经常会用到16进制,而十进制的使用非常少,这是因为16进制和二进制有天然的联系:4个 二进制位可以表示从0到15的数字,这刚好是1个16进制位可以表示的数据,也就是说,将二进制转换成16进制只要每4位进行转换就可以了。
  二进制的“00101000”直接可以转换成16进制的“28”。字节是电脑中的基本存储单位,根据计算机字长的不同,字具有不同的位数,现代电脑的字长一般是32位的,也就是说,一个字的位数是32。字节是8位的数据单元,一个字节可以表示0-255的十进制数据。对于32位字长的现代电脑,一个字等于4个字节,对于早期的16位的电脑,一个字等于2个字节。


位–bit(比特)

  在我们看完上文之后,大家或多或少应该已经理解了什么是二进制,二进制是规则,那么实现的承载就是位(bit)
位:英文bit,音译为“比特”,表bai示二进制位。位:英文bit,音译为“比特”,表bai示二进制位。
  为了让大家深入理解一下什么是位(比特),我在这里用java的原始数据类型来举例一下。
我们目前一共有8个java原始数据类型,以后会不会增加,我不知道,你也不知道,废话我不多说,我先列个表放在下面让大家看一下。

序号 原始数据类型 大小
1 byte (字节) 8位[比特(bit)]
2 short (短整数) 16位[比特(bit)]
3 int(整型) 32位[比特(bit)]
4 long(长整型) 64位[比特(bit)]
5 float(单精度浮点) 32位[比特(bit)]
6 double(双精度浮点) 64位[比特(bit)]
7 char(单字符) 16位[比特(bit)]
8 boolean(布尔值) 1位[比特(bit)]

  看看能猜到什么,再看看bit的位置,结果已经出来了吧,那就是:
  bit(位):是数据存储(计算机中信息)的最小单位,并只能存储0和1


java中如何进行位移操作

  为了说我接下的证明,我要先做下提前量:

 十进制如何转成二进制

举例数值:9
开始转化:

在这里插入图片描述
如果该基本类型为int类型时,位数不够时高位补0,
二进制的最高位用来判断数值的正负,例如:最高位为1,代表负数,0为正数。
所以结果为 0000 0000 0000 0000 0000 0000 0000 1001
这是十进制数值为正数的情况下,那如果为负数呢?下边就是我将要说的:

 原码,反码,补码

概念:
  1. 正数的补码和反码与原码相同
  2. 负数的反码是原码取反,补码是原码取反+1
  3. 计算机中的数值一律用补码存储

接下来继续说如果是负数的话那么如何转成计算机中存储的二进制呢?

举例数值:-9
因为是负数所以根据概念中2和3的内容开始转化:

扫描二维码关注公众号,回复: 11637700 查看本文章
  • 首先获取9的原码,借用上面的例子,我们知道它的原码为:
    0000 0000 0000 0000 0000 0000 0000 1001
  • 然后将32位9的二进制取反获得反码:
    1111 1111 1111 1111 1111 1111 0110
  • 最后加1获得补码,也是最终存储到计算机中的值:
    1111 1111 1111 1111 1111 1111 0111

下面就是重点了,我们将要用java中的位移操作来证明java中二进制,在证明之前,先举例一些位移操作的用法:

  • <<n: 左移,高位移除n位,低位补0
  • >>n: 右移{
    • 正数:低位移除n位,高位补0
    • 负数:低位移除n位, 高位补1
      }
  • >>>n: 逻辑右移:无论正负,低位移除n位,高位补0

下面我将要用左位移右位移作为例子来详细讲下在二进制层面,它们到底是怎么操作的:

 左位移操作例子:

操作数据:-9<<3
  1. 根据上面的内容,我们知道-9的补码为:

1111 1111 1111 1111 1111 1111 0111

  1. <<3 原理 :高位移除3位(bit) ,低位补0,结果为:

1111 1111 1111 1111 1111 1111 1011 1000

  1. 翻译为十进制,因为 首位为1 所以为负数:
  • 补码->反码(-1):

1111 1111 1111 1111 1111 1111 1011 0111

  • 反码->原码:

0000 0000 0000 0000 0000 0000 0100 1000

  • 原码二进制转成十进制为 :

20*0+ 21*0+ 22*0+ 23*1+ 24*0+ 25*0+ 26*1 = 72

  • 因为是负数,所以最后结果为 -72

用代码证明一下:

		System.out.printf("左位移最后结果:%d\n",-9<< 3);

效果:
在这里插入图片描述

 右位移操作例子:

操作数据:-9>>3
  1. 根据上面的内容,我们知道-9的补码为:

1111 1111 1111 1111 1111 1111 0111

2.>>3 原理 :因为被操作数为负数,所以低位移除3位(bit) ,高位补1,结果为:

1111 1111 1111 1111 1111 1111 1111 1110

  1. 翻译为十进制,因为 首位为1 所以为负数:
  • 补码->反码(-1):

1111 1111 1111 1111 1111 1111 1111 1101

  • 反码->原码:

0000 0000 0000 0000 0000 0000 0000 0010

  • 原码二进制转成十进制为 :

20*0+ 21*1= 2

  • 因为是负数,所以最后结果为 -2

用代码证明一下:

		System.out.printf("左位移最后结果:%d\n",-9>> 3);

效果:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_38316697/article/details/107762913