计算机基础原理记录

学校学的都还给老师了,╮(╯▽╰)╭哎

原码、反码、补码

   首先计算机里面保存的数据都是由二进制组成0、1,既然有数据就有正负之分。
原码就是这些二进制的组合,首位为符号位,0表示正数,1表示负数。
例如1的4位二进制就是0001,-1的4位二进制就是1001
原码通俗点说就是给人看的,但是计算机需要对二进制进行运算啊,例如1+(-1)应该等于0,
如果用原码进行求和就是0001+1001=1010 变成了十进制的(-2),结果不对啊,为了解决这个问题就引导出
了反码的概念,反码是用来处理负数的,
正数的反码就是本身,负数反码就是符号位置不变,其他位置变反过。

还是刚刚的例子,1+(-1)=0001+1110=1111  反码1111的原码等于(1000)等于十进制的(-0),按道理
0不应该有正负之分,为了解决这个问题,引入了补码的概念,同样,补码是用来处理负数的,
正数的补码就是其本身,负数的补码就是在反码的基础上+1。(负数的补码是在原码的基础上除符号位外其余位取反后+1)
  原码            反码           补码
0001+(1001)=》0001+1110=》0001+1111(1110+1)=10000,去掉最高位就是0000,解决了-0的问题。
由此推导出计算机在运算中用的都会补码方式进行计算。
在Java中,所有数据的表示方法都是以补码的形式表示
补码与原码关系:
正数补码与原码相同,负数补码是原码减1后取反。

%运算

通过取模操作可以获取某个数之间的随机数,例如 a%10 可以获取到0~9之间随机值

&运算

与运算 如果相对应位都是1,则结果为1, 否则为0 规则 :都为1时才为1

|运算

如果相对应位都是0,则结果为0,否则为1,有一个为1,则为1

~运算

按位取反运算符翻转操作数的每一位,即0变成1,1变成0。
非运算是根据补码来计算的

例如 5的非运算
~5= -6
// 5的原码0101 取反就是  1010
 // 1010 求反码 1101 求补码 1110

20180920-Java位运算的使用场景

1、乘法 a * (2^n) 等价于 a << n
    3*2=3<<1
    3*4=3<<2
2、除法  a / (2^n) 等价于 a>> n
    8/2=8>>1
    8/4=8>>2
3、取模运算,采用位运算实现 a % (2^n) 等价于 a & (2^n - 1)
    9%4=9&3
首先位移运算肯定是高效的,jdk源码有大量使用
    (1)机器都是使用补码,运算也是使用补码运算。
    (2)正数的原码补码反码都一样。
    (2)补码与原码相互转换,其运算过程是相同。
带符号左位移运算符<< ,数值的补码全部往左移动X位: a<<1 等于a*2 ,左移n位就相当于乘以2的n次方
例如1<<1 等于0001向左边位移一位,00010
带符号右位移运算符>>  a>>1 等于a/2  ,右移n位就相当于除以2的n次方
&与运算,就是按位与运算,两个1才是1,否则都是0
例如2&1 等于0010和0001 与运算,结果就是0000。
一般常用的就是某个数a&1,那么结果要么是0要么是1。

掩码使用例子

例如权限控制,例如增删改查四个权限控制
如果是组合权限那么会有16种情况
这时候我们就可以用二进制来实现
1<<0 0001 增
1<<1 0010 删
1<<2 0100 改
1<<3 1000 查
假设flag=0

添加增权限就是 :
flag=(flag|0001)=0001


删除 增的这个权限(0001)就是:
flag&=~0001

1、 ~0001=1000(去反数)
2、0001&(1000)=0000 (再和原来的数取与)




判断限就是
& 是两个都是1 才会大于0
flag&0010=(0001&0001)>0

 public static class RoleCodeMask {
        //教师0001
        public static final int teacherRoleCode = 1 << 0;
        //校长0010
        public static final int principalRoleCode = 1 << 1;
        //教导0100
        public static final int subjectLeaderRoleCode = 1 << 2;
        //当前状态
        private int currentStatus;

        public void add(int code) {
            currentStatus = currentStatus | code;
        }

        public boolean contains(int code) {
            return (currentStatus & code) > 0;
        }

        // 当前权限是 0111 教师、校长、教导
        // 删除教师权限0001,则 0111 &
        public void delete(int more){
        // 如果非操作不好理解,可以理解为 减(-)操作也是可以的
            // currentStatus = currentStatus - more;
            currentStatus &= ~more;
        }


    }

进制之间转化

核心思路是求余数求商
例如10进制转2进制
   int i=110112;
    String two="";
     while (i>0){
         two=i%2+two;
         i=i/2;
     }

编译与解释

java文件->编译->.class文件,编译成.class字节码,.class需要jvm解释,然后解释执行
   。Java很特殊,Java程序需要编译但是没有直接编译成机器语言,即二进制语言,而是编译成字节码(.class)再用解释方式
   执行。java程序编译以后的class属于中间代码,并不是可执行程序exe,不是二进制文件,
   所以在执行的时候需要一个中介来解释中间代码,这既是java解释器,也就是所谓的java虚拟机(JVM),也叫JDK。