前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >二进制相关基础知识

二进制相关基础知识

作者头像
海拥
发布2021-08-23 15:21:23
2990
发布2021-08-23 15:21:23
举报
文章被收录于专栏:全栈技术全栈技术

二进制

1 什么是二进制

二进制:逢二进一的计数规则。

  1. 计算机底层 也就是 数据类型都是2进制的! int long float double 等 都是2进制的!
    1. int 类型内部是 32位2进制数,8位称为1个字节,32位2进制数也称为4字节
    2. long 类型内部是 64位2进制数,8位称为1个字节,64位2进制数也称为8字节
    3. float double 内部采用 浮点数2进制表示 IEEE-754标准,今天不讨论
  2. 计算机内部为啥使用2进制:2进制的制造成本最低!

计算机如何处理10进制和2进制:

在这里插入图片描述
在这里插入图片描述

案例:

代码语言:javascript
复制
public class Demo01 {

	public static void main(String[] args) {
		/*
		 * 1 Java内部一切数据都是2进制的! 如 int n 在内存中就是2进制 
		 * 
		 */
		int n = 50; //编译期间,将"50"转化为110010, 程序执行时候 n 就是110010
		System.out.println(n); //输出时候 println 方法将 110010 转化为“50”输出
		//Java 提供了输出数据2进制的功能,利用这个功能就可以显示数据的2进制,在内存中的情况
		System.out.println(Integer.toBinaryString(n)); 
		
		n = 51;
		System.out.println(Integer.toBinaryString(n)); 
		
		for(int i=0; i<100; i++) {
			System.out.println(Integer.toBinaryString(i)); 
		}
		/*
		00000000 00000000 00000000 00000000
		00000000 00000000 00000000 00000001
		00000000 00000000 00000000 00000010
		00000000 00000000 00000000 00000011
		00000000 00000000 00000000 00000100
		00000000 00000000 00000000 00000101
		00000000 00000000 00000000 00000110
		00000000 00000000 00000000 00000111
		00000000 00000000 00000000 00001000
		00000000 00000000 00000000 00001001
		00000000 00000000 00000000 00001010 = 8+2 = 10
		00000000 00000000 00000000 00001011
		00000000 00000000 00000000 00001100
		00000000 00000000 00000000 00001101
		00000000 00000000 00000000 00001110
		00000000 00000000 00000000 00001111
		 */
	}

}

2 什么是16进制

  1. 逢16进一的计数规则
  2. 进制直接量,书写冗长麻烦!计算机编程语言采用16进制作为2进制的缩写
  3. 缩写规则:2进制从最低位开始,每4位缩写为1位16进制数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9LLQzYIv-1592906210850)(2.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9LLQzYIv-1592906210850)(2.png)]

案例:

代码语言:javascript
复制
public class Demo02 {

	public static void main(String[] args) {
		/*
		 * Java 7 以后提供了2进制直接量语法,前缀0b开头的2进制直接量
		 * 2进制直接量,书写冗长麻烦!
		 */
		int n = 0b110010; //50
		System.out.println(Integer.toBinaryString(n)); 
		n = 0b1001111101000101010001001011111;// 2进制直接量,书写冗长麻烦!
		System.out.println(Integer.toBinaryString(n));
		n = 0x4fa2a25f; //利用16进制缩写2进制,使用方便
		System.out.println(Integer.toBinaryString(n));
		
		n = 0b11001111101000101010001001011111;
		System.out.println(n); 
	}

}

3 补码

计算机中负数的编码。其目的是解决负数问题。

设计思想:将固定位数的2进制数分一半作为负数使用的一种编码。

基本运算规则:

  1. 固定位数,计算时候,超过固定位数就自动溢出舍弃,始终保持固定的位数
  2. 将高位为1的数作为负数使用
  3. 采用倒推的方式为负数编码

以4位数补码位例子研究补码。然后推广到32位(int)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bzlAeznh-1592906210851)(3.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bzlAeznh-1592906210851)(3.png)]

案例:

代码语言:javascript
复制
public class Demo03 {
	public static void main(String[] args) {
		/*
		 * 验证int\long类型的补码编码
		 * 
		 */
		int max = Integer.MAX_VALUE;
		int min = Integer.MIN_VALUE;
		System.out.println(max);
		System.out.println(min);
		System.out.println(Integer.toBinaryString(max));
		System.out.println(Integer.toBinaryString(min));
		
		long lmax = Long.MAX_VALUE;
		long lmin = Long.MIN_VALUE;
		System.out.println(Long.toBinaryString(lmax));
		System.out.println(Long.toBinaryString(lmin));
		
		int n = -1;
		System.out.println(Integer.toBinaryString(n)); 
		long l = -1L;
		System.out.println(Long.toBinaryString(l)); 
		
		System.out.println("如何认识负数:");
		System.out.println(Integer.toBinaryString(n)); 
		int m = -4;
		System.out.println(Integer.toBinaryString(m)); 
		System.out.println(Integer.toBinaryString(-12)); 
		System.out.println(Integer.toBinaryString(-44)); 
		/*
		 * 如何认识负数:
				11111111111111111111111111111111   -1
				11111111111111111111111111111100   -1-1-2 = -4
				11111111111111111111111111110100   -1-1-2-8= -12
				11111111111111111111111111010100   -1-1-2-8-32 = -44
				11111111111111111111111111001111   -1-16-32 = -49
		 */
		for(int i=-200; i<0; i++) {
			System.out.println(Integer.toBinaryString(i));
		}	
	}
}

补码互补对称:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-510Z3qFM-1592906210853)(4.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-510Z3qFM-1592906210853)(4.png)]

案例

代码语言:javascript
复制
public class Demo04 {

	public static void main(String[] args) {
		/*
		 *  测试补码的互补对称现象: -n = ~n+1  min除外
		 *  ~ 取反计算:将2进制每个位进行翻转 1变0,0变1
		 */
		int n = 20;
		int m = ~n + 1; //m为n的相反数 -20
		System.out.println(m);
		//分析运算过程:
		System.out.println(Integer.toBinaryString(n)); 
		System.out.println(Integer.toBinaryString(~n)); 
		System.out.println(Integer.toBinaryString(~n+1)); 
		/*
		   n   =    00000000000000000000000000010100  16+4   = 20  
		   ~n  =    11111111111111111111111111101011  -1-4-16=-21
		   ~n+1=    11111111111111111111111111101100  -1-1-2-16=-20
		 */
		

	}

}

int类型的编码:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4XuoSaqX-1592906210855)(5.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4XuoSaqX-1592906210855)(5.png)]

经典面试题目:

代码语言:javascript
复制
System.out.println(~80+1);

上述代码的输出结果:( B ) A.-79 B.-80 C.-81 D.-82

代码语言:javascript
复制
System.out.println(~-80+1);

上述代码的输出结果:( B ) A.79 B.80 C.81 D.82

代码语言:javascript
复制
System.out.println(~80);

上述代码的输出结果:( C ) A.-79 B.-80 C.-81 D.-82

4 二进制运算符

常见运算符

代码语言:javascript
复制
取反  ~
与运算 &
或    |
右移位 >>>
数学又移位 >>
左移位 <<

与运算 & (逻辑乘法)

基本运算规则:有0则0

代码语言:javascript
复制
0 & 0 -> 0
0 & 1 -> 0
1 & 0 -> 0
1 & 1 -> 1

运算时候讲两个数字对齐位数,对应位进行与计算。

举个例子:

代码语言:javascript
复制
           7   7    d   d    d   e    7   d     
n      =   01110111 11011101 11011110 01111101
m      =   00000000 00000000 00000000 11111111  mask 掩码
k=n&m      00000000 00000000 00000000 01111101   

如上代码的运算意义:n的最后8位数被截取下来,存储到了k中,经常用于截取数据部分位计算,这种计算称为“掩码(Mask)运算”。 其中m称为“掩码”,按照1的个数是8个称为8位掩码。

代码案例:

代码语言:javascript
复制
int n = 0x77ddde7d;
int m = 0xff;
int k = n & m;
System.out.println(Integer.toBinaryString(n));
System.out.println(Integer.toBinaryString(m));
System.out.println(Integer.toBinaryString(k));

>>> 右移位计算

运算规则:将2进制数整体向右移动,低位自动溢出舍弃,高位补0。

举个例子:

代码语言:javascript
复制
n      =  01101111 11101111 00110111 10110111 
n>>>1  =  001101111 11101111 00110111 1011011 
n>>>2  =  0001101111 11101111 00110111 101101 
n>>>8  =  00000000 01101111 11101111 00110111 
b3=(n>>>8) & 0xff;
          00000000 00000000 00000000 00110111

代码:

代码语言:javascript
复制
int n = 0x6fef37b7;
int m = n>>>1;
int k = n>>>2;
int g = n>>>8;
int b1 = (n>>>24) & 0xff;
int b2 = (n>>>16) & 0xff;
int b3 = (n>>>8) & 0xff;
int b4 = (n>>>0) & 0xff;
//按照2进制输出 n m k g b3 
//如何计算 b1 b2 b3 b4 ?

将一个整数拆分为4个字节

代码语言:javascript
复制
              b1       b2       b3       b4 
n       =  01110111 11011101 11011110 01111101
b1      =  00000000 00000000 00000000 01110111
b2      =  00000000 00000000 00000000 11011101
b3      =  00000000 00000000 00000000 11011110
b4      =  00000000 00000000 00000000 01111101
案例:
int b1 = (n>>>24) & 0xff;
int b2 = (n>>>16) & 0xff;
int b3 = (n>>>8) & 0xff;
int b4 = (n>>>0) & 0xff;

| 或运算(逻辑加法)

基本规则:有1则1

代码语言:javascript
复制
0 | 0 -> 0
0 | 1 -> 1
1 | 0 -> 1
1 | 1 -> 1

将两个2进制数字对齐位数,对应位进行或运算。

举个例子:

代码语言:javascript
复制
n          = 00000000 00000000 00000000 10110101
m          = 00000000 00000000 10110111 00000000
k = n|m      00000000 00000000 10110111 10110101

如上案例的意义:n和m两个数进行拼接,k中低8位数是n,高8位数是m

案例:

代码语言:javascript
复制
int n = 0xb5;
int m = 0xb700;
int k = n | m;
//按照2进制检测 n m k

<< 左移位计算

将2进制数字的整体向左移动,高位自动溢出,低位补0;

举个例子:

代码语言:javascript
复制
n        = 10111011 10101110 10000011 11010001
m = n<<1   0111011 10101110 10000011 110100010
k = n<<2   111011 10101110 10000011 1101000100
g = n<<8   10101110 10000011 11010001 00000000

代码:

代码语言:javascript
复制
int n = 0xbbae83d1
int m = n<<1;
int k = n<<2;
int g = n<<8;
//按照2进制输出 n m k g

将4个字节数据合并为一个int整数:

代码语言:javascript
复制
b1      =  00000000 00000000 00000000 01110111
b2      =  00000000 00000000 00000000 11011101
b3      =  00000000 00000000 00000000 11011110
b4      =  00000000 00000000 00000000 01111101

b1<<24  =  01110111 00000000 00000000 00000000 
b2<<16  =  00000000 11011101 00000000 00000000 
b3<<8   =  00000000 00000000 11011110 00000000 
b4      =  00000000 00000000 00000000 01111101
合并:n = (b1<<24)|(b2<<16)|(b3<<8)|b4
              b1       b2       b3       b4
n       =  01110111 11011101 11011110 01111101

代码:

代码语言:javascript
复制
int b1 = 0x77;
int b2 = 0xdd;
int b3 = 0xde;
int b4 = 0x7d;
int n = (b1<<24)|(b2<<16)|(b3<<8)|b4;
//按照2进制检测 b1 b2 b3 b4 n 

移位计算的数学意义 和 >>

2进制中,数字整体向左移动一次扩大2倍(溢出情况除外)

举个例子:

代码语言:javascript
复制
n         = 00000000 00000000 00000000 00000110     6
m = n<<1    0000000 00000000 00000000 000001100    12
k = n<<2    000000 00000000 00000000 0000011000    24
...

经典面试题目:

表达式 n * 8 可以替换为( n<<3 ) (被乘数是2的整次幂)

>> 称为数学右移位计算,运算结果相当于数学除法(溢出时候向小方向取整数)

>>移位时候: 正数高位补0,负数高位补1

>>> 移位时候:无论正负,高位都补0

举个例子(负数)

代码语言:javascript
复制
n     =  11111111 11111111 11111111 10011100   -1-1-2-32-64 -100
m =n>>1  111111111 11111111 11111111 1001110   -1-1-16-32    -50
k =n>>2  1111111111 11111111 11111111 100111   -1-8-16       -25
g =n>>3  11111111111 11111111 11111111 10011   -1-4-8        -13 
f =n>>>1 011111111 11111111 11111111 1001110   正数

>>>逻辑右移位计算,不管符号,将数字整体向右移动

>> 数学右移位计算,有符号移位,符合数学计算结果

  1. 如果为了替代数学计算就使用 >>
  2. 如果为了数字整体向右移动,不考虑数学结果,就使用 >>>

经典面试题目:

表达式 n / 8 (n>0)可以替换为( n>>3 ) (除数是2的整次幂)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-06-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二进制
    • 1 什么是二进制
      • 2 什么是16进制
        • 3 补码
          • 4 二进制运算符
            • 与运算 & (逻辑乘法)
            • >>> 右移位计算
            • | 或运算(逻辑加法)
            • << 左移位计算
            • 移位计算的数学意义 和 >>
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档