JavaSE入门学习41:文件传输基础之二进制基础

Posted life is wonderful

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE入门学习41:文件传输基础之二进制基础相关的知识,希望对你有一定的参考价值。

      一进制概述

      1)二进制:用数字0和1表示,计算机内部用二进制,运算简单,简化了计算机结构。

      2)八进制:标志的开头用0表示,用0~7的数字表示。适用于12位和36位计算机系统。

      3)十六进制:标志的开头用0x表示,用0~9,,A,B,C,D,E,F表示。表示表达长度短,变得更常用。

      4)位权:一个数码在不同的位置所代表的值不同。

      计算机常用的进制表:


      二进制转换

      常用进制的换算如下表:


      以上关于进制和进制转换的详细可以看我转载的文章:计算机各进制之间的转换

      三进制的位运算

      常用的位运算如下表:


       位运算的优点:特定情况下,计算方便,速度快,支持面广。

       (1)按位与(&)

       计算规则:两个二进制数位如果全为1,结果才1,其余的情况均为0。也就是:0&0=0、0&1=1、1&0=1、

1&1=1。

       例如:51&5即(0011 0011)&(0000 0101) = (0000 0001),因此51&5=1。

       按位与运算的特殊用法:

       1)清零:如果想将一个单元清零,即使其全部二进制数位都为0,只要与一个各位都为零的数值相与,结果为零。

       2)取一个数中指定位:方法是找一个数,对应x要取的位,该数的对应位为1,其余位为零,此数与x进行与运算可

以得到x中的指定位。

       例如:设x=(1010 1110),要求是取x的低4位(即从右端开始计数的四个二进制数位),用x&(0000 1111) = (0000

 1110)即可得到。

       (2)按位或(|)

       计算规则:只要二进制数位有一个为1,结果就为1。也就是说:0|0=0、0|1=1、1|0=1、1|1=1。

       例如:51|5 即(0011 0011) | (0000 0101) = (0011 0111) 因此51|5=55。

       按位或的特殊用法:

       常用来对一个数据的某些数位置为1:方法就是找到一个数,对应x要置1的位,该数的对应位为1,其余位为零,

此数与x相或可使x中的某些位置1。

       例如:将x=(1010 0000)的低4位置为1,用x | (0000 1111) = (1010 1111)即可得到。

       (3)异或运算(^)

       计算规则:两个二进制数位相对应不同,则该位结果为1,否则为0,也就是:0^0=0、0^1=1、1^0=1、1^1=0。

       例如:51^5即(0011 0011) ^ (0000 0101) = (0011 0110) 因此51^5=54。

       异或运算的特殊用途:

       1)使特定位翻转,找一个数,对应x要翻转的各位,该数的对应位为1,其余位为零,此数与x对应位异或即可。

       例如:x=(1010 1110),使x低4位翻转,用x ^ (0000 1111) = (1010 0001)即可得到。

       2)与0相异或,保留原值。

       例如:x=(1010 1110),用x ^ (0000 0000) = (1010 1110)即可保证。

       拓展:两个变量交换值的方法

       1)借助第三个变量来实现:C=A;A=B;B=C。

       2)利用加减法实现两个变量的交换:A=A+B;B=A-B;A=A-B。

       3)用位异或运算来实现:A=A^B;B=A^B;A=A^B。原理:利用一个数异或本身等于0和异或运算符合交换律,也是

交换效率最高的一种方法。

       (4)取反运算(~)

       计算规则:对一个二进制数按位取反,即将0变1,1变0,也就是:~1=0、~0=1。

       例如:(1010 0001)按位求反的结果为(0101 1110)。

       (5)左移运算(<<)

       计算规则:将一个运算对象的各二进制数位全部左移若干位,左边的二进制位丢弃,右边补0。

       例如:2(0000 0010) << 1 = 4(0000 0100)。

       若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。

       例如:-14(其补码是1111 0010) << 2 = (左移两位后补码为1100 1000) = -56。

                 11(0000 1011) << 2 = (0010 1100) = 44。

       例如第一个只需要该补码的原码对应的正值,然后取相反数

       1)补码减1得到反码:(1100 0111)

       2)反码取反得到原码(即该负数的正值):(0011 1000)

       3)计算正值:(56)

       4)取相反数:(-56)

       (6)右移运算(>>)

       计算规则:将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。操作数每右移一位,相

当于该数除以2。左补0或者补1得看被移数是正还是负。

       例如:4(0000 0100)  >> 2 = (0000 0001) = 1。

                  -14(其补码是1111 0010) >> 2 = (右移两位后补码为1111 1100) = -4。

      (7)无符号右移运算(>>>)

      计算规则:各个位向右移指定的位数。右移后左边空出的位用零来填充,移出右边的位被丢弃。

      例子:-14 >>> 2

                 =(其补码为11111111 11111111 11111111 11110010) >>> 2

                 =(无符号右移两位后补码为00111111 11111111 11111111 11111100)

                 =1073741820

      拓展:

      负数以其正值的补码形式表示。反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,

但符号位除外。

      1)原码:一个正数按照绝对值大小转换成的二进制数称为原码。

      例如:(00000000 00000000 00000000 00001110)是14的原码。

      2)反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。

      例如:(00000000 00000000 00000000 00001110)每一位取反

             得(11111111 11111111 11111111 11110001)

             得(11111111 11111111 11111111 11110001)

      注意:(11111111 11111111 11111111 11110001)和(00000000 00000000 00000000 00001110)互为反码。

      3)补码:反码加1称为补码。

      例如:(11111111 11111111 11111111 11110001)+1 = (11111111 11111111 11111111 11110010)。

      因此-14的二进制表示为:      

      -14(11111111 11111111 11111111 11110010) >>> 2 =(00111111 11111111 11111111 11001000)

      四Java内置的进制转换

      在java中整数默认是int类型的,int类型占4字节(4*8=32bit)。

      实例代码:

public class Test{
      public static void main(String[] args){
            //十进制转换为其它进制
            System.out.println(Integer.toBinaryString(112));//二进制
            System.out.println(Integer.toHexString(112));//十六进制
            System.out.println(Integer.toOctalString(112));//八进制

            //其它进制转换为十进制
            System.out.println(Integer.parseInt("111001",2));//二进制
            System.out.println(Integer.parseInt("27",8));//十六进制
            System.out.println(Integer.parseInt("A8",16));//八进制
      }
}

       输出结果:


       五Java中的进制

       (1)Java中二进制用的多吗?

       平时开发中"进制转换"和"位操作"用的不多,Java处理的是高层。在跨平台中用的较多,如:文件读写,数据通

信。

       (2)Java中数据类型

       基本数据类有以下四种:


       (3)int类型转换为字节数组

       8143(00000000 00000000 00011111 11001111)

       => byte[] b=[-49,31,0,0] 

       第一个低端字节:8143 >> 0*8 & 0xff=(11001111)=207(或有符号-49)

       第二个低端字节:8143 >> 1*8 & 0xff=(00011111)=31

       第三个低端字节:8143 >> 2*8 & 0xff=(00000000)=0

       第四个低端字节:8143 >> 3*8 & 0xff=(00000000)=0

       拓展:

       1)小端法:指的是低位字节排放在内存的低地址端即该值的起始地址,高位字节排放在内存的高地端。

       2)大端法:指的是高位字节排放在内存的低地址端即该值的起始地址,低位字节排放在内存的高地端 。

       例子如下图所示:   

    

       (4)字符串转换为字节数组

       String s;

       byte[] bs=s.getBytes();

       (5)字节数组转化为字符串

       byte[] bs=new byte[int];

       String s=new String(bs); 

       或者String s=new String(bs,encode);//encode指编码方式:gb2312,utf-8

       实例1:

public class Convert{
    //int转化为byte[]
    public static byte[] int2Bytes(int id){
        byte[] arr=new byte[4];
        for(int i=0;i<arr.length;i++){
            arr[i]=(byte)((int)(id>>i*8)&0xff);
        }
        return arr;
    }

    //byte[]转化为int
    public static int bytes2Int(byte[] arr){
        int result=0;
        for(int i=0;i<arr.length;i++){
            result+=(int)((arr[i]&0xff)<<i*8);
        }
        return result; 
    }

    public static void main(String[] args) throws Exception{
        byte[] arr=Convert.int2Bytes(8143);
        System.out.println(arr[0]+","+arr[1]+","+arr[2]+","+arr[3]);

        System.out.println(Convert.bytes2Int(arr));
    }
}

       运行结果:


       实例2:

public class Convert{
    //long转化为byte[]
    public static byte[] long2Bytes(int id){
        byte[] arr=new byte[8];
        for(int i=0;i<arr.length;i++){
            arr[i]=(byte)((long)(id>>i*8)&0xff);
        }
        return arr;
    }


    //byte[]转化为long
    public static int bytes2Long(byte[] arr){
        int result=0;
        for(int i=0;i<arr.length;i++){
            result+=(long)((arr[i]&0xff)<<i*8);
        }
        return result; 
    }


    public static void main(String[] args) throws Exception{
        String describe="我是一名Java软件工程师";
        byte[] barr=describe.getBytes();
        System.out.println(barr[0]+","+barr[1]+","+barr[2]+","+barr[3]);

        String des=new String(barr);
        System.out.println(des);
    }
}

       运行结果:


以上是关于JavaSE入门学习41:文件传输基础之二进制基础的主要内容,如果未能解决你的问题,请参考以下文章

JavaSE入门学习43:文件传输基础之I/O流

JavaSE入门学习44:文件传输基础之I/O流

JavaSE入门学习46:文件传输基础之I/O流(Java序列化)

JavaSE入门学习7:Java基础语法之语句(下)

JavaSE入门学习9:Java基础语法之数组

JavaSE入门学习6:Java基础语法之运算符和语句(上)