Java 二进制

  • 1.二进制 八进制 十六进制转换
  • 二进制,十六进制赋值
  • 2.补码
  • 3.二进制运算
  • 取反: ~
  • 与运算: &
  • 或运算: |
  • 右位移运算: >>>
  • 左移位运算: <<
  • 右移位运算:>>
  • 扩展



计算机只有1和0,这就是二进制

我们平常看到的10,20等等都是十进制,是由二进制转换过来的

1.二进制 八进制 十六进制转换

下面的例子带你从十进制转换成二进制,八进制和十六进制

int a =11;
//Integer.toBinaryString( )的返回值是String类型
System.out.println(Integer.toBinaryString( a));//十进制转换成二进制 输出是:1011
System.out.println(Integer.toOctalString(a));//十进制转换成八进制 输出是:13
System.out.println(Integer.toHexString(a));//十进制转换成十六进制 输出是:b
//大家注意在16进制中10是a,11是b,12是c,13是d,14是e,15是f
  • 一般来说1个字节是8位,在案例中int类型是32位,所以正常输出是32位,但是你只能看到4位1011->8+2+1=11,是因为前面有28个0,为了方便就去掉了
  • 8位输出的是13代表着1*8+3=11

二进制,十六进制赋值

//二进制
int binary = 0b11;
//十六进制
int hex = 0xff;

2.补码

那么有些同学可能在想有正数和负数,负数一般怎么表示。

负数是整型的第一位是1

例如int是32位,

  • 第一位是1代表这个数是负数,不加入计算,注意计算的时候必须要加-1
  • 1111 1111 1111 1111 1111 1111 1111 1111代表着-1
  • 1111 1111 1111 1111 1111 1111 1111 1110代表着-2=-1-(1)
  • 1111 1111 1111 1111 1111 1111 1111 1101代表着-3=-1-(2)
  • 1111 1111 1111 1111 1111 1111 1111 1100代表着-4=-1-(2+1)
  • 1111 1111 1111 1111 1111 1111 1111 1011代表着-5=-1-(4)
  • 等等

下面是一个例子:

System.out.println(Integer.toBinaryString(-22));
//输出是11111111111111111111111111101010=-1-(1+4+16)=-22
//	    00000000000000000000000000010101

那什么是补码,假如一个二进制的数是1101很明显这是一个负数是-3,那么他的补码就是 3,但是1101反过来应该是0010=2,少了个1,所以补码的规则是 -n=~n+1

例子:

int a =-5;
System.out.println(Integer.toBinaryString(a));
//a的补码是-1   		  输出为101
System.out.println(Integer.toBinaryString(-a));
//我们用补码规则做~n+1    输出为101  
System.out.println(Integer.toBinaryString(~a+1));

3.二进制运算

运算符号

运算规则

~

取反

&

与运算

|

或运算

>>>

右位移运算

>>

数学右位移运算

<<

左位移运算

取反: ~

例子: 1101 取反就是0010

与运算: &

只有运算两边都是1输出才是1,01,10,00输出都是0

输入

输入

输出

0

0

0

0

1

0

1

0

0

1

1

1

例子:

/*			1100
       &	0101
输出: 		0100			*/
Byte demo = 0b1100 & 0b0101;
System.out.println(Integer.toBinaryString(demo));//输出是0100

或运算: |

或运算除了00是0,其他都为1

输入

输入

输出

0

0

0

0

1

1

1

0

1

1

1

1

例子:

/*			1100
       &	0101
输出: 		1101			*/
Byte demo = 0b1100 | 0b0101;
System.out.println(Integer.toBinaryString(demo));//输出是1101

右位移运算: >>>

>>> 逻辑右移位:数字向右移动,低位自动溢出,高位补0, 结果没有数学意义

例子:

int a = 0x2222;
System.out.println(Integer.toBinaryString(a));	  //10001000100010
System.out.println(Integer.toBinaryString(a>>>1));//1000100010001

上个例子可以很清晰的看到向右移了一位,最后一个0就删除了

左移位运算: <<

2进制数字整体向左移动,高位自动溢出,低位补0
数学意义就是向左移一格就是乘2,移两格就是乘两个2,移三格就是乘3个2

int a = 0b10;
System.out.println(Integer.toBinaryString(a));			//输出:10    =2
System.out.println(Integer.toBinaryString(a<<1));		//输出:100	  =4
System.out.println(Integer.toBinaryString(a<<2));		//输出:1000  =8

原因在于向右移,就是把2的移到4的位置去,所以数学意义是移一格乘2

右移位运算:>>

数学右移位:数学向右移动,低位自动溢出,正数高位补0,负数高位补1, 移动一次数学除以2,小方向取整数。如果是替代数学 /2, 使用数学右移位

int a = 0b1000;
System.out.println(Integer.toBinaryString(a));		//输出:   1000  =8
System.out.println(Integer.toBinaryString(a>>1));	//输出:	  100	=4
System.out.println(Integer.toBinaryString(a>>2));	//输出:   10	=2

扩展

将一个32位int分成4个字节,再合并
思路:

  • 分成4个字节:先与运算再向右移
  • 合并:4个字节左移位再或运算
//分开整数
int a = 0x12345678;//原整数
//先与运算,再向右移动24,让0x12到达最右边
int a1 = (a & 0xff000000) >>> 24;
//先与运算,再向右移动16,让0x34到达最右边;先右移位再右运算也是一样的结果
int a2 = (a & 0xff0000) >>> 16;
//先与运算,再向右移动8,让0x56到达最右边
int a3 = (a & 0xff00) >>> 8;
//0x78本身就在最右边,直接与运算就行
int a4 = a & 0xff;
//a输出是:10010001101000101011001111000
System.out.println(Integer.toBinaryString(a)); 
System.out.println(Integer.toBinaryString(a1));//输出是:0001,0010 =12
System.out.println(Integer.toBinaryString(a2));//输出是:0011,0100 =34
System.out.println(Integer.toBinaryString(a3));//输出是:0101,0110 =56
System.out.println(Integer.toBinaryString(a4));//输出是:0111,1000 =78
//合并整数
int aNew = (a1<<24) | (a2<<16) | (a3<<8) | a4;
//aNew输出是:10010001101000101011001111000
System.out.println(Integer.toBinaryString(aNew));