bit

bit是计算机的最小的存储单元,一切数据最终都以bit的形式存放在计算机之中。

一个bit有且只有两种状态。要么是0,要么是1。像这样:

多个bit组合在一起就可以构成更复杂的数据。例如,8个bit组合在一起就构成了一个byte

0 1 1 1 1 1 1 1

byte

在Java中,byte是基本的数据类型,是一个有符号,也就是有正负之分的整数。最大值是127,最小值是-128

127

127在计算机内部是如何存储的呢?当然是以二进制形式存储:

0 1 1 1 1 1 1 1

8个bit,右边是低位,左边是高位。黄色的bit是符号位,0表示正数,1表示负数。

-128

-128呢?

看着挺好解释的,2的7次方 = 128,符号位是1代表它是负数。是这样吗?

-1

-1的二进制表示如下:

1 1 1 1 1 1 1 1

是不是什么神奇?怎么会是8个1?要解释这个问题,就需要知道原码、反码、补码。

原码、反码、补码

原码

原码是数值对应的二进制表示形式,例如:

0: 0 0 0 0  0 0 0 0
1: 0 0 0 0  0 0 0 1
2: 0 0 0 0  0 0 1 0

对于正数,计算机存的就是原码。

-1的原码表示如下:

1 0 0 0 0 0 0 1

可是,对于负数,计算机存的是其补码。

反码

反码是对原码中的bit位取反,0110。符号位除外,因为符号位表正负,不表数值。

原码:1 0 0 0 0 0 0 1
反码:1 1 1 1 1 1 1 0

补码

补码是在反码的基础上加1。还拿-1举例:

你是否理解补码了呢?考你一道题,-2在计算机里是如何表示的?

位运算

Java支持取反异或等运算,接下来我一一举例。

取反

取反操作的运算符号是~,这个操作符可以将操作数的bit位逐一翻转。1001

例如:

 a: 0 1 0 1 0 1 0 1
~a: 1 0 1 0 1 0 1 0

与运算的操作符号是&,它将两个操作数的bit位一一比对。如果记录比对结果呢?——规则如下:

  • 如果两个操作数的bit位同时为1,则记1
  • 否则,记为0

例如:

  a: 0 0 0 0 1 1 1 1
  b: 1 1 1 1 0 0 0 1
a&b: 0 0 0 0 0 0 0 1 

或运算的操作符是|,它将两个操作数的bit位一一比对。如果记录比对结果呢?——规则如下:

  • 如果两个操作数的bit位有一个为1,则记为1
  • 否则,记为0
  a: 0 0 0 0 1 1 1 0
  b: 1 1 1 1 1 1 1 0
a|b: 1 1 1 1 1 1 1 0 

亦或

亦或的操作符是^,它也是一一比较两个操作数的bit位,规则如下:

  • 如果两个bit位相同,则记为0
  • 否则,记为1
  a: 0 0 0 0 1 1 1 1
  b: 1 1 1 1 1 1 1 0
a^b: 1 1 1 1 0 0 0 1

位移

byteshortintlong等整数都支持位移,也就是将bit位整体向左或者向右移动。

左移

左移的运算符为<<,它是这样操作输入数据的:

  • 从左到右,每个bit都向左←移动
  • 一个bit一个坑,左数第一个bit移出去,不要了
  • 第2个bit占第1个bit的坑
  • 第3个bit占第2个bit的坑,如此类推
  • 最后会空出来一个bit位,用0补充

例如:

   a: 0 0 0 0 0 0 0 1
a<<1: 0 0 0 0 0 0 1 0

<<相当于对原数字做乘2操作。

如果是负数呢?

     -1: 1 1 1 1 1 1 1 1
-1 << 1: 1 1 1 1 1 1 1 0

还记得前面的考题吧?计算机是如何存储-2的?

原码:1 0 0 0 0 0 1 0
反码:1 1 1 1 1 1 0 1
补码:1 1 1 1 1 1 1 0

-1 << 1等于-2

右移(带符号位)

带符号位右移的操作符号是>>,它是这样操作的:

  • 从右边第一个bit开始,逐一向右侧移动
  • 第1个bit向右移,没地儿了,舍弃它
  • 第2个bit向右移动到第1个bit的坑
  • 第3个bit向右移动到第2个bit的坑,以此类推
  • 符号位依旧向右移动
  • 符号位补充空出来的左边第一个位置

例如:

   a: 0 0 0 0 0 0 1 0
a>>1: 0 0 0 0 0 0 0 1

>>1相当于把原数做除2的操作。再举一个负数的例子:

   a: 1 0 0 0 1 0 0 0
a>>1: 1 1 0 0 0 1 0 0

1 0 0 0 1 0 0 0代表的是什么数呢?如果它是一个byte,只有8个bit,它就是-120。在Java中,可以加上0b前缀,告诉计算机这是二进制数(binary)。

System.out.println((byte) 0b10001000);
// -120

那如何用眼睛看出来呢?补码是怎么来的呢?

原码 → 反码 → 补码

逆转回去就知道原码了,也就是:补码 → 反码 → 原码:

  • 既然补码是反码+1来的,那补码-1就是反码了。
  • 既然反码是原码取反得来的,那对反码取反就能得到原码。(不忘了符号位不变)

例如:

补码:1 0 0 0 1 0 0 0
反码:1 0 0 0 0 1 1 1
原码:1 1 1 1 1 0 0 0

右移(不带符号位)

>>>>>的区别是,它是这样操作的:

  • 从右边第一个bit开始,逐一向右侧移动
  • 第1个bit向右移,没地儿了,舍弃它
  • 第2个bit向右移动到第1个bit的坑
  • 第3个bit向右移动到第2个bit的坑,以此类推
  • 符号位依旧向右移动
  • 0补充空出来的左边第一个位置

例如:

    a: 0 0 0 0 0 0 1 0
 a>>1: 0 0 0 0 0 0 0 1
a>>>1: 0 0 0 0 0 0 0 1

再举个负数的例子:

    a: 1 0 0 0 1 0 0 0
 a>>1: 1 1 0 0 0 1 0 0
a>>>1: 0 1 0 0 0 1 0 0

上面讲的都是移动1个bit,也可以移动多个bit的,例如:

     a: 0 0 0 0 0 0 0 1
  a<<1: 0 0 0 0 0 0 1 0
  a<<2: 0 0 0 0 0 1 0 0
  a<<3: 0 0 0 0 1 0 0 0
  a<<4: 0 0 0 1 0 0 0 0
  a<<5: 0 0 1 0 0 0 0 0
  a<<6: 0 1 0 0 0 0 0 0
  a<<7: 1 0 0 0 0 0 0 0
  a<<8: 0 0 0 0 0 0 0 0
  a<<9: 0 0 0 0 0 0 0 0
a<<100: 0 0 0 0 0 0 0 0 

bit 和 byte的更多相关文章

  1. weblogic漏洞总结 复现(未完)

    复现方式 Docker复现 WEBlogic爆出了很多漏洞 先了解一下现在主流的版本 Weblogic 10.3.6.0 Weblogic 12.1.3.0 Weblogic 12.2.1.1 Web ...

  2. go语言:多个[]byte数组合并成一个[]byte

    场景:在开发中,要将多个[]byte数组合并成一个[]byte,初步实现思路如下: 1.获取多个[]byte长度 2.构造一个二维码数组 3.循环将[]byte拷贝到二维数组中 package gst ...

  3. Android-Drawable、Bitmap、byte[]、资源文件相互转换

    我们在Android的开发中,经常可以遇到图片的处理,当中,有很多是 Bitmap.Drawable.byte[]和资源文件它们直接相互转换. 今天就此总结一下: 1.资源文件转为Drawable 2 ...

  4. byte[] 转成图片方法

    /// <summary> /// ImageData 的摘要说明 /// </summary> public class ImageData : IHttpHandler { ...

  5. flask+sqlite3+echarts2+ajax数据可视化报错:UnicodeDecodeError: 'utf8' codec can't decode byte解决方法

    flask+sqlite3+echarts2+ajax数据可视化报错: UnicodeDecodeError: 'utf8' codec can't decode byte 解决方法: 将 py文件和 ...

  6. .NET和JAVA中BYTE的区别以及JAVA中“DES/CBC/PKCS5PADDING” 加密解密在.NET中的实现

    场景:java 作为客户端调用已有的一个.net写的server的webservice,输入string,返回字节数组. 问题:返回的值不是自己想要的,跟.net客户端直接调用总是有差距 分析:平台不 ...

  7. 用java String类的getBytes(String charsetName)和String(byte[] bytes, String charsetName)解决乱码问题

    Java中String的数据是如何存储的,查看源代码就可以知道,String的数据是存储在char[] value这样一个成员变量中的,char类型的大小在java中是2个字节 我们还知道,现在普遍使 ...

  8. 字节、字、bit、byte的关系

    字 word 字节 byte 位 bit 字长是指字的长度 1字=2字节(1 word = 2 byte) 1字节=8位(1 byte = 8bit)  一个字的字长为16 一个字节的字长是8 bps ...

  9. Stream与byte[]与Image与string

    public byte[] GetByteImage(Image img) { byte[] bt = null; if (!img.Equals(null)) { using (MemoryStre ...

  10. int[] convert byte[]

    private void button_Click(object sender, RoutedEventArgs e) { byte[] bytes = this.ConvertIntArrayToB ...

随机推荐

  1. BZOJ 1072: [SCOI2007]排列perm [DP 状压 排列组合]

    题意:给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0) 100%的数据满足:s的长度不超过10, 1<=d<=1000, 1<=T<=15 看到整 ...

  2. 2018/1/27 Zookeeper实现分布式锁

    public class DistributedClient { // 超时时间 private static final int SESSION_TIMEOUT = 5000; // zookeep ...

  3. 发放春节福利,ASP.NET Core断点续传

    ASP.NET Core断点续传 在ASP.NET WebAPi写过完整的断点续传文章,目前我对ASP.NET Core仅止于整体上会用,对于原理还未去深入学习,由于有园友想看断点续传在ASP.NET ...

  4. CentOS安装编译Lua

    Lua介绍 Lua 是一个小巧的脚本语言.是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Robert ...

  5. 针对Eclipse的maven Missing artifact com.microsoft.sqlserver:slqjdbc4:jar:4.0

    maven 中添加sqlserver 出错,报错内容 maven Missing artifact com.microsoft.sqlserver 解决方法这里先下载好jar包 ,然后maven命令执 ...

  6. 如何在Centos 7上用Logrotate管理日志文件

    何为Logrotate? Logrotate是一个实用的日志管理工具,旨在简化对系统上生成大量的日志文件进行管理. Logrotate允许自动旋转压缩,删除和邮寄日志文件,从而节省宝贵的磁盘空间. L ...

  7. Python基础——数据类型与基本运算【主要为除法】

    Python版本:3.6.2  操作系统:Windows  作者:SmallWZQ 无论是Python 3.x版本还是2.x版本,Python均支持多种数据类型,能够直接处理的数据类型包括Int类型. ...

  8. Python自动化--语言基础2--运算符、格式化输出、条件语句、循环语句、列表、元组

    运算符包括:算术运算符.比较运算符.赋值运算符.逻辑运算符.成员运算符.身份运算符 算术运算符 %   取模(余数) //  取相除的整数部分 /   (5/2=2.5) 比较运算符 ==  等于 ! ...

  9. 利用FileReader实现上传图片前本地预览

    引子 平时做图片上传预览时如果没有特殊的要求就直接先把图片传到后台去,成功之后拿到URL再渲染到页面上,这样做在图片比较小的时候没什么问题,大一点的话就会比较慢才能看到预览了,而且还产生了垃圾文件,所 ...

  10. Yii小部件

    小部件 Yii提供了一套数据小部件widgets,这些小部件可以用于显示数据. DetailView小部件用于显示一条记录数据. ListView和GridView小部件能够用于显示一个拥有分页.排序 ...