二进制-JAVA

二进制

什么是2进制

逢2进1的计数规则

案例:

public static void main(String[] args) {
	/**
	 * Java 先编译在运行, 运行期间所有数据都是2进制的。
	 * 1. Java在编译时候将10进制转换为2进制
	 * 2. 变量中存储的数据都是2进制的!
	 * 3. 在显示的时候,Java将2进制转换为10进制显示
	 */
	int n = 155; //"59" -> 111011
	System.out.println(n);//111011 -> "59"
	//Java 提供了API 可以展示 Java底层2进制数实际情况
	System.out.println(Integer.toBinaryString(n));  
	/*
	 * 输出0~200之间的2进制,并且挑选20个数据,手工计算其10进制值
	 */
	for(int i=0; i<200; 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
00000000 00000000 00000000 00001011
00000000 00000000 00000000 00001100
00000000 00000000 00000000 00001101
00000000 00000000 00000000 00001110 = 8+4+2 = 14
00000000 00000000 00000000 00001111 = 8+4+2+1 = 15
10000
10001

00000000 00000000 00000000 10011011 = 128+16+8+2+1 = 155

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

16进制

逢16进1的计数规则, 计算机行业采用16进制缩写2进制!

  1. 2进制不方便书写,冗长繁琐
  2. 由于16进制的基数的2进制基数的4次幂,2进制的每4位数可以缩写为1位16进制。将2进制从最低位开始,每4位数可以缩写为1位16进制。

案例:

public static void main(String[] args) {
	/**
	 * Java 7 提供了2进制字面量前缀 0b
	 * 0x是16进制前缀
	 */
	int n = 0b111011;
	System.out.println(n); 
	//    4   3   e    b   f    5   f
	n = 0b0100_00111110_10111111_01011111;
	int m = 0x43ebf5f;
	System.out.println(Integer.toBinaryString(n));
	System.out.println(Integer.toBinaryString(m));
	
}

补码

补码是计算机中处理有符号数(正数和负数)的底层编码。

补码编码设计规则:将固定位数的2进制,分一半作为负数使用。 计算时候,多出的位数自动溢出舍去。

采用4位数2进制数据,讨论其补码编码规律。 然后再推广到32位或者64位整数。

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

public static void main(String[] args) {
	/**
	 * 测试最大值和最小值的编码
	 */
	int max = Integer.MAX_VALUE;
	int min = Integer.MIN_VALUE;
	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));
	
}

补码互补对称

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

11111111 11111111 11111111 11111101  -3
00000000 00000000 00000000 00000010   2  ~-3
00000000 00000000 00000000 00000011   3  ~-3+1

负数的 编码值

  1. 记住-1的编码
  2. 考察某个负数编码比-1少多少个权
11111111111111111111111111111111   -1
11111111111111111111111111111001  =-1-2-4=-7
11111111111111111111111110011001  =-1-2-4-32-64=-103

11111111111111111111111111011001  =-1-2-4-32=?
11111111111111111111111111011010
11111111111111111111111111011011
11111111111111111111111111011100
11111111111111111111111111011101
11111111111111111111111111011110
11111111111111111111111111011111

企业面试题目:

如下代码的运算结果( C )
System.out.println(~100+1);
A.-98 B.-99 C.-100 D.-101

如下代码的运算结果( C )
System.out.println(~-100+1);
A.98 B.99 C.100 D.101

如下代码的运算结果( B )
System.out.println(~-100);
A.98 B.99 C.100 D.101

如下代码的运算结果( D )
System.out.println(~100);
A.-98 B.-99 C.-100 D.-101

2进制运算符

运算符:

~取反 &与 |或  >>>右移位 >>数学右移位  <<左移位

& 与运算

运算规则:逻辑乘法, 有0则0

0 & 0 => 0
0 & 1 => 0
1 & 0 => 0
1 & 1 => 1

运算时候将两个2进制数字对齐位,对应的位进行与计算

举个栗子:

          7   d    8   8    f   e    9   d   
n   =     01111101 10001000 11111110 10011101
                                     f   f
m   =     00000000 00000000 00000000 11111111 mask 面具 掩码
k = n&m   00000000 00000000 00000000 10011101

如上代码的意义:n的最后8位数被截取存储到了k中,如上计算称为“掩码运算”, 将最低位开始连续1个的个数称为掩码的位数。

验证:

int n = 0x7d88fe9d;
int m = 0xff;
int k = n&m;
//按照2进制输出 n m k

右移位运算 >>>

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

举个栗子:

            b1       b2       b3       b4
n    =   01111011 00100110 00110010 10011110
m=n>>>1  001111011 00100110 00110010 1001111 
k=n>>>2  0001111011 00100110 00110010 100111
g=n>>>8  00000000 01111011 00100110 00110010
b3=(n>>>8) & 0xff;
b4=n & 0xff; 

代码:

int n = 0x7b26329e;
int m = n>>>1;
int k = n>>>2;
int g = n>>>8;
int b3 = (n>>>8) & 0xff;
int b4 = n & 0xff;
int b2 = (n>>>16) & 0xff;
int b1 = (n>>>24) & 0xff;

将一个整数拆分为4个Byte

int n = 12387912;
int b1 = (n>>>24) & 0xff;
int b2 = (n>>>16) & 0xff;
int b3 = (n>>>8) & 0xff;
int b4 = n & 0xff;

或运算 |

运算规则:逻辑加法, 有1则1

0 | 0 => 0
0 | 1 => 1
1 | 0 => 1
1 | 1 => 1

计算时候将两个2进制数对齐位数,对应位进行或运算

举个栗子:

n      =     00000000 00000000 00000000 10110100
m      =     00000000 00000000 10111101 00000000
k=n|m        00000000 00000000 10111101 10110100 

如上代码的意义:在数据错位情况下,两个字节数据被拼接在一起,拼接为一个16位数

代码:

int n = 0xb4;
int m = 0xbd00;
int k = n|m;
//按照2进制输出 n m k 

左移位运算 <<

运算规则:将2进制数整体向左移动,高位会自动溢出舍弃,低位补0,如果高位0变成1是正常现象,称为符号位溢出。

举个栗子:

n    =   01101111 11010000 10001110 00010101
m=n<<1   1101111 11010000 10001110 000101010
k=n<<2   101111 11010000 10001110 0001010100 
g=n<<8   11010000 10001110 00010101 00000000

代码:

int n = 0x6fd08e15;
int m = n<<1;
int k = n<<2;
int g = n<<8;
//按照2进制输出数据

将4个Byte拼接为一个整数

JAVA开发中一般采用int类型存储byte数据,将byte数据存储在int类型的低8位。

b1  =   00000000 00000000 00000000 10111001
b2  =   00000000 00000000 00000000 01101111
b3  =   00000000 00000000 00000000 10110111
b4  =   00000000 00000000 00000000 11011101
           b1       b2       b3       b4
n   =   10111001 01101111 10110111 11011101

b1<<24  10111001 00000000 00000000 00000000 
b2<<16  00000000 01101111 00000000 00000000 
b3<<8   00000000 00000000 10110111 00000000 
b4      00000000 00000000 00000000 11011101
n = (b1<<24) | (b2<<16) | (b3<<8) | b4;

移位计算的数学意义

向左移位一次数字扩大2倍, 向右移动一次数字缩小2倍

>>> 称为逻辑右移位,数字整体向右移动,无论正负,低位溢出,高位都补>> 称为数学右移位,数字整体向右移动,低位溢出,整数时候高位补0,负数时候高位补1. 高位补1可以保证符号不变,结果是数学除以2向小方向取整数。

>>> 目的是单纯的将数位向右移动,不关心数值!如果仅仅是为了移动数位就使用 >>>

>> 目的是数学除法,除以2向小方向取整数,如果为了替代数学除法,请使用 >>

举个栗子:

n  =    11111111 11111111 11111111 11001110 =-1-1-16-32=-50
m=n>>1  111111111 11111111 11111111 1100111 =-1-8-16=-25
m=g>>2  1111111111 11111111 11111111 110011 =-1-4-8 =-13
k=n>>>1 011111111 11111111 11111111 1100111 = 大
public static void main(String[] args) {
	int n = 5;//0b101;
	System.out.println(n<<1);
	System.out.println(n<<2);
	System.out.println(n<<3);
	System.out.println(n<<4);
	System.out.println(n<<5);
	
	n = 80;
	System.out.println(n>>1);
	System.out.println(n>>2);
	System.out.println(n>>3);
	System.out.println(n>>4);
	System.out.println(n>>5);
}

面试题目:

可以将运算 n*8 替换为( n<<3 )

可以将运算 n/8 替换为( n>>3 )

在面试代码题中: size/2 替换为 size>>1

作业

  1. 将一个long类型拆分为8个byte
  2. 将8个byte数据拼接为一个long类型数据

n<<5);

	n = 80;
	System.out.println(n>>1);
	System.out.println(n>>2);
	System.out.println(n>>3);
	System.out.println(n>>4);
	System.out.println(n>>5);
}

面试题目:

可以将运算 n*8 替换为( n<<3 )

可以将运算 n/8 替换为( n>>3 )

在面试代码题中: size/2 替换为 size>>1

作业

  1. 将一个long类型拆分为8个byte
  2. 将8个byte数据拼接为一个long类型数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵培风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值