原码,补码,反码
-
在计算机中,用8位来保存一个子节,就是8bit=1byte(字节)
现在计算机一般是64位的,所以是8个子节 -
我现在用-2来举例说明原码,补码和反码
-
原码:10000010
-
反码:
其中正数的反码和补码是一样的
负数的反码就是:将原码的除了符号位不变,其他位按照位来取反,
所以-2的反码就是:11111101 -
补码:
其中正数的补码和原码还是一样的
负数的补码就是对应的反码+1
-2的补发就是:11111110 -
在计算机里面是使用补码的方式来保存数据的,但是为什么呢?
因为计算机里面有个加法器,计算机使用加法器可以实现数值的加法,但是我们不想在计算机中再做一个减法器,想使用加法器来实现减法,所以就让计算机使用补码来存储数据,这样加法器可以实现减法,但是为什么可以实现呢?我们使用1-1来做例说明一下:
1-1=1+(-1)=0
我们有三种方式保存数据,所以现在有三种解决的方案
1)使用原码:1+(-1)=00000001+1000001=100000010=-2 /显然这种解决方案不行
2)使用反码:1+(-1)=00000001+11111110=1111111
这样计算出来的是反码,我们将它转化成原码就是:10000000,这样表示1-1=-0,这样我们就使用了两种方式来表示0,其中10000000表示-0,00000000表示+0,这样我们觉得还是不合理,
3)使用补码:1+(-1)=00000001+11111111=00000000
这个是补码,但是它是正数,所以补码和原码相同,所以就是0所以因为上面,计算机里面存储的数据都是使用补码来存放的
位运算
(注意:计算机都是用补码进行运算的)
-
位运算符包括:
1.1数值1<<数值2
//左移,数值1的二进制数向左边移动数值2个位,相当于数值1*2^数值2 比如:3<<2=12
1.2(数值1>>数值2) //这里在浏览器上(>>)转义了,所以我加了()才能显示,右移高位空出的位置,如果本来最高位是0就补0,如果高位是1就全部补1,比如:3>>1=1
1.3>>> //无符号右移,注意点,就是无符号右移是右移后空出的高位里面一律补0 比如:3>>>1=1
1.4 & //与运算,就是将两边的数字的二进制(因为计算机储存数值的方式就是二进制)的每一个位都进行与运算,就是11的结果才是1,10,01,00的结果都是0 ,比如:6&3=2
1.5 | //或运算,也是二进制每个位的或,有一个1结果就是1,比如:6|3=7
1.6 ^ //异或运算,顾名思义,就是不同才是1,相同就是0 ,比如:6^3=5
1.7 ~ //取反运算,就是二进制按位取反 ,比如:~6=-7,这里也可以看到为什么原码取反后+1才是补码 -
在Java中一些对于进制转换的函数:
2.1 Integer.toBinaryString(int) //这就是返回二进制的补码
2.2 (byte)Integer.parseInt(String) //就是将String转化成二进制
练习
package test;
/*
* 需求是这样:将n和m两个数进行交换
*/
public class Binarytest
{
public static void main(String[] args)
{
method1();
method2();
method3();
}
//提供一个临时变量
public static void method1()
{
int m=10,n=20;
int temp;
temp=m;
m=n;
n=temp;
System.out.println("m="+m+" n="+n);
}
//没有提供临时变量,但是当两个数较大的时候会出现精度损失
public static void method2()
{
int m=10,n=20;
m=m+n;
n=m-n;
m=m-n;
System.out.println("m="+m+" n="+n);
}
//这里就是一个两全其美的方法
//这里使用了一个结论,就是异或运算的结论:
//当(m^n)^n时,就时m本身
public static void method3()
{
int m=10,n=20;
m=m^n;
n=m^n;//(m^n)^n=m
m=m^n;//(m^n)^m=n
System.out.println("m="+m+" n="+n);
}
}
这里还有一个其他应用示例,就是数字1和数字2进行与运算,就可以去出数字1中对应数字2的位数个数的位
例如:60&15就是取出60对应最低位4位的对应的值