整数有四种类型,byte/short/int/long,分别占1/2/4/8个字节,即分别占8/16/32/64位
二进制使用最高位表示符号位,用1表示负数,用0表示正数。
byte a = -1,如果只是将最高位变为1,二进制应该是10000001,但实际上,它应该是11111111。
byte a=-127,如果只是将最高位变为1,二进制应该是11111111,但实际上,它却应该是10000001。
和我们的直觉正好相反,这是什么表示法?这种表示法称为补码表示法,而符合我们直觉的表示称为原码表示法,补码表示就是在原码表示的基础上取反然后加1。取反就是将0变为1,1变为0。
负数的二进制表示就是对应的补码表示,比如说:
-1:1的原码表示是00000001,取反是11111110,然后再加1,就是11111111。
-2:2的原码表示是00000010,取反是11111101,然后再加1,就是11111110。
-127:127的原码表示是01111111,取反是10000000,然后再加1,就是10000001。
给定一个负数二进制表示,要想知道它的十进制值,可以采用相同的补码运算。比如:10010010,首先取反,变为01101101,然后加1,结果为01101110,它的十进制值为110,所以原值就是-110。直觉上,应该是先减1,然后再取反,但计算机只能做加法,而补码的一个良好特性就是,对负数的补码表示做补码运算就可以得到其对应整数的原码,正如十进制运算中负负得正一样。
byte类型,正数最大表示是01111111,即127,负数最小表示(绝对值最大)是10000000,即-128,表示范围就是 -128到127。其他类型的整数也类似,负数能多表示一个数。
注意 两个数字相加时 应保持二进制的位数相同,位数不够时在符号位之后添加0补齐。
二进制的运算算术运算二进制的加法:0+0=0,0+1=1 ,1+0=1, 1+1=10(向高位进位);
二进制的减法:0-0=0,10-1=1(向高位借位) 1-0=1,1-1=0 (模二加运算或异或运算) ;
二进制的乘法:0 * 0 = 0 0 * 1 = 0,1 * 0 = 0,1 * 1 = 1 二进制的除法:0÷0 = 0,0÷1 = 0,1÷0 = 0 (无意义),1÷1 = 1
public static void main(String[] args) {
/**
* 1、<< : 左移运算符:符号位不变,高位溢出,低位补0,对补码进行操作
* 2、十进制--> 二进制补码 --->操作补码 --> 将补码取补码 -->十进制
* 3、过程(二进制):
* a、6 的二进制补码(32位):00000000 00000000 00000000 00000110;
* b、向左偏移两位后补码:00000000 00000000 00000000 00011000;
* c、补码-->补码-->十进制:24
* 4、打印结果为: 24
*/
System.out.println("6 << 2 ===== " +(6 << 2));
/**
* 1、<< : 左移运算符: 符号位不变,高位溢出,低位补0,对补码进行操作
* 2、十进制--> 二进制补码 --->操作补码 --> 将补码取补码 -->十进制
* 3、过程(二进制):
* a、6 的二进制补码(32位):11111111 11111111 11111111 11111010;
* b、向左偏移两位:11111111 11111111 11111111 11101000;
* c、补码-->补码-->十进制:-24
* 4、打印结果为: -24
*/
System.out.println("-6 << 2 ===== " +(-6 << 2));
/**
* 1、>> : 右移运算符: 符号位不变,低位溢出,高位用符号位补高位,对补码进行操作
* 2、十进制--> 二进制补码 --->操作补码 --> 将补码取补码 -->十进制
* 3、过程(二进制):
* a、6 的二进制补码(32位):00000000 00000000 00000000 00000110;
* b、向左偏移两位:00000000 00000000 00000000 00000001;
* c、补码-->补码-->十进制:1
* 4、打印结果为:1
*/
System.out.println("6 >> 2 ===== " +(6 >> 2));
/**
* 1、>> : 右移运算符: 符号位不变,低位溢出,高位用符号位补高位,对补码进行操作
* 2、十进制--> 二进制补码 --->操作补码 --> 将补码取补码 -->十进制
* 3、过程(二进制):
* a、-6 的二进制补码(32位):11111111 11111111 11111111 11111010;
* b、向左偏移两位:11111111 11111111 11111111 11111110;
* c、补码-->补码-->十进制:-2
* 4、打印结果为:-2
*/
System.out.println("-6 >> 2 ===== " +(-6 >> 2));
/**
* 1、>>> : 无符号右移(无符号的意思是将符号位当作数字位看待): 低位溢出,高位补0,对补码进行操作
* 2、十进制--> 二进制补码 --->操作补码 --> 十进制
* 3、过程(二进制):
* a、6 的二进制补码(32位):00000000 00000000 00000000 00000110;
* b、向左偏移两位:00000000 00000000 00000000 00000001;
* c、补码-->十进制:1
* 4、打印结果为:1
*/
System.out.println("6 >>> 2 ===== " +(6 >>> 2));
/**
* 1、>>> : 无符号右移(无符号的意思是将符号位当作数字位看待): 低位溢出,高位补0,对补码进行操作
* 2、十进制--> 二进制补码 --->操作补码 -->十进制
* 3、过程(二进制):
* a、-6 的二进制补码(32位):11111111 11111111 11111111 11111010;
* b、向左偏移28位:00000000 00000000 00000000 00001111;
* c、补码-->十进制:15
* 4、打印结果为:15
*/
System.out.println("-6 >>> 28 ===== " +(-6 >>> 28));
}
按位与的应用:
1.清零操作;
如果想把一单元清零(使他的二进制全为0),那么让它的每一位&0,结果就为0.