java 二进制 文件I/O 2进制和10进制的转换 程序实现 以及移位

1详细二进制

(主要是用于基本i/o流)

#二进制:

1、计算机内部都是2进制

2、数组和ArrayList的区别:ArrayLlsit里面有算法(通用算法,只有当通用算法不行的时候,可以自己写专门算法),数组没有相应的算法,但就底层而言都是数组数组结构。

#什么是二进制

1、逢21的计数规则

数字:0 1

权:256 128 64 32 16 8 4 2 1

基数:2

#为什么使用2进制

>______________________________________________________________________________________________________________________________

进制的在计算机运行计算成本最低, 可以支持任何的数学运算,在进行下面方法的时候:

int i=56;

System.ou.prinln(i);

实际上程序暗自调度了下面的方法:(下面的两个函数十分重要,他们的性能影响java的性能)

--->Integer.parseIne();--->56---> 2 进制

--->Integer.toString();--->2进制--->转换为10进制

我们可以对上面程序进行设置断点,单步调试(F5),依次进入到方法之中:

<

 public static String toString(int i) {

        if (i == Integer.MIN_VALUE)

            return "-2147483648";

        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);

        char[] buf = new char[size];

        getChars(i, size, buf);

        return new String(0, size, buf);

    }

  static int stringSize(int x) {

        for (int i=0; ; i++)

            if (x <= sizeTable[i])

                return i+1;

    }

 static void getChars(int i, int index, char[] buf) {

        int q, r;

        int charPos = index;

        char sign = 0;

 

        if (i < 0) {

            sign = '-';

            i = -i;

        }

        // Generate two digits per iteration

        while (i >= 65536) {

            q = i / 100;

        // really: r = i - (q * 100);

            r = i - ((q << 6) + (q << 5) + (q << 2));

            i = q;

            buf [--charPos] = DigitOnes[r];

            buf [--charPos] = DigitTens[r];

        }

 

        // Fall thru to fast mode for smaller numbers

        // assert(i <= 65536, i);

        for (;;) {

            q = (i * 52429) >>> (16+3);

            r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...

            buf [--charPos] = digits [r];

            i = q;

            if (i == 0) break;

        }

        if (sign != 0) {

            buf [--charPos] = sign;

        }

 

     String(int offset, int count, char value[]) {

this.value = value;

this.offset = offset;

this.count = count;

    }

>

>__________________________________________________________________________________________________________________________

###2进制与10进制的转换

> 因为10 进制用于计数,2进制也可以用于计数,转换是指,当前相同个数的时候,10 进制的数字和2进制数字是相同的数字

> 计算机类不处理是2进制的。编程语言是将10值的转换为2机制的交给计算机处理,编程语言给使用者留下错觉:计算机能够直接处理10进制巍数据

2进制--->10进制方法:

11012=8+4+1=1310

总结:各个位数跟权乘后相加

10进制-->2进制的转换方法

1、短除法

2、或者根据权值来计算

<

 程序实现:

public class Demo{

   public static void mian (args[] String){

int n =234;

// Integer.toBinaryString(int n)转换为二进制

System.out.println(Integer.toBinaryString(n));

}

// 可以验证你的计算转换是否正确。

}

>

##16进制

116进制是2进制的简写形式

22进制书写过于冗长不便

316进制的一位数可以简写二进制的四位数

16进制计数规则:

数字:0 1 2 3 4 5 6 7 8 9 A B C D E F

权值:256 16 1

基数:16

##补码:因为计算机底层无法放负数,所以将2^32,其中2^31表示负数(最高位1表示负数,但是从计算机角度来说,是一个很大的正数),剩下的2^31表示正数,

>___________________________________________________________________________________________________________________________________

> 是一种算法 已经封成为方法了:

Integer.toString()

Integer.paraInt()

补码:32位的最大值:0x7fffffff

                  的最小值:0x80000000

补码特点:

补码的最大值:

int max=0f7fffffff

System.out.println(Integer.toBinaryString(max))

补码的最小值:

int min=0x80000000

System.out.printlin(Integer.toBinaryString(min))

程序实现:求-1 的补码:

public class Demo {

public static void main(String[] args) {

// TODO 自动生成的方法存根

int n=-1;

System.out.println(n);

System.out.println(Integer.toBinaryString(n));

}

}

输出:111....321

>_________________________________________________________________________________________________________________________

经典例题:

<

      public class Demo {

public static void main(String[] args) {

// TODO 自动生成的方法存根

int n=Integer.MAX_VALUE;

System.out.println(n);

System.out.println(Integer.toBinaryString(n));

}

 

}

输出:1111111111111111111111111111111(请看清楚311,尽管内存中是01111111111111111111111111111111,但是控制台输出时会不是最前面的0省略!!!)

>

>_________________________________________________________________________________________________________________________________

1、溢出结果不是无规律!

2、正数溢出不一定负数

3、负数溢出也不一定正数

4n=(max+1)*2+n

5min=max+1

>____________________

相反数:

补码的对称现象:-n=~n+1(取反+1)---->但是这个规律不适合两头极值(最大值和最小值)

经典面试题

System.outprintln(~8+1);//-8

System.outprintln(+1)

>

按照2进制的每个位进行计算的运算符  ~ & | >>> >> <<

### ~ 取反运算(略)

 

### >>>  逻辑右移位运算  

规则:将数据的每一个位向有移动

n:0000 0000 0000 0000 0000 0000 0011 0010

m=n>>>1

m:0000 0000 0000 0000 0000 0000 0001 1001

m=n>>>2

m0000 0000 0000 0000 0000 0000 0000 1100

测试代码:

public class Demo {

public static void main(String[] args) {

int x=0x5d8c8;

int n=50;

int m=n >>> 2;

System.out.println(Integer.toBinaryString());

}

}

### <<  逻辑左移位运算  

规则:将数据的每一个位向有移动

代码测试:

public class Demo {

public static void main(String[] args) {

int n=50;

int m=n << 2;

System.out.println(m);

 

}

}

 

###移动运算的数学意义

> 引子:移动小数点运算

347720. 小数点向右移动一次

347720. 数据*10

假设小数点不动,则数字向右移动,数字向左移动一次,原数据向左移动一次。原数据*10

如上规律 --->二进制依然成立

经典例题:

--->如何优化将n*8运算?答案:移位运算(n<<3

运算规则:

---当正数的情况下,左侧补0

---当负数的情况下,左侧补1,保存符号不变

例子:

n=11111111 11111111 11110111 11110100

int n=0xfffff7f4;

int m1=n>>>1;(在前面添加0 无论正负)

//m1:01111111 111111111 11110111  1111010

int m2=n>>1;(按正负号在前面添加01

//m2:11111111 11111111 11111011  11111010

 

########将两个数据对其的位置进行“与&”以及“或||”运算

运算规则:

1&1=1  1||1=1

1&0=0  1||0=1

0&1=0  0||1=1

0&0=0  0||0=0

测试代码:

int n=0x6db7b65

int mask=0xffffffd5;

int x=a&mask

int y=a||mask

######### 掩码

1 用于将数据的一部分截取出来。

2 掩码运算2的整次幂的余数

(掩码的运算性能是比除法的强----->面试:如何优化是除法 n%8 的性能:答案 :n&0x7)

0000%4=00   0000&0011=00

0011%4=11   0011&0011=11

0010%4=10       ...

0001%4=01 ...

0100%4=00 ...

3 掩码的运算用途:将整数进行拆分

测试代码:

public class Demo {

public static void main(String[] args) {

int n=0x6d64c311;

      System.out.println(Integer.toBinaryString(n));

    int b1=(n>>>24)&0xff;

  int b2=(n>>>16)&0xff;

    int b3=(n>>>8)&0xff;

    int b4=(n>>>0)&0xff;

//合并操作

    int m=(b1<<24)|(b2<<16)|(b3<<8)|b4;//可以将|换为+ ,但是注意一点,+会有进位。

    System.out.println(Integer.toBinaryString(m));

}

}

############认识read()方法

  文件:

11101011 01110111 11011011 11011101    EOF

0    1        2          3             4

       ^

int b=readInt();

b1=00000000 00000000 00000000 11101011

       11101011 01110111 11011011 11011101      EOF

0     1       2          3    4

                 ^

       int b1=readInt();

b2=00000000 00000000 00000000 01110111

................

       int b4=readInt();//读到文件末尾,返回-1

       b4=11111111 1111111 11111111 11111111

        读取后然后将通过移位和与运算

       int n=(b1<<24)|(b2<<16)|(b3<<8)|b4

        -------->读取n的值

(原因:文件在读取操作时,每次只能读取文件的低八位的字节数,也就是1byte,所以就造成了上述的现象)  

 

#########认识write();

认识读写RandomAccessFile

write(int b) 向文件中写出一个byte

int b=read() 向中读取一个byte

write(byte[] buf) 向文件中写出一批 byte

read(byte[] buf)从文件中添加一批文件

控制文件的读写位置:getFilePoint seek()

#########

测试代码:

import java.io.IOException;

import java.io.UnsupportedEncodingException;

 

public class Demo2 {

/**

        *UTF-8 是国际化的最优国际编码

 * @param args

 * @throws IOException

 */

public static void main(String[] args) throws IOException {

String str="今天你吃了吗?";

for(int i=0;i<str.length();i++){

char c=str.charAt(i);

System.out.println(Integer.toBinaryString(c));

}

/*getBytes()

         *将字符串序列化为byte数据的方法

         *(字符串序列化=字符串的编码,字符串编码的方案之一“UTF-16BE)

         *如果添加一些字母,会浪费了8个字节的空间,因为中文16个字节,而字母的只需8个字节表示造成的

         */

byte[] buf=str.getBytes("UTF-16BE");

for(int b:buf){

System.out.println(Integer.toBinaryString(b&0xff));

}

}

 

}


##########

测试代码UTF-8

import java.io.IOException;

import java.io.UnsupportedEncodingException;

 

public class Demo2 {

public static void main(String[] args) throws IOException {

String str="今天你吃了吗?www";

for(int i=0;i<str.length();i++){

char c=str.charAt(i);

System.out.println(Integer.toBinaryString(c));

}

System.out.println("UTF-8方案如下:");

byte[] buf=str.getBytes("UTF-8");

for(int b:buf){

System.out.println(Integer.toBinaryString(b&0xff));

}

}

 

}

输出:

100111011001010

101100100101001

100111101100000

101010000000011

100111010000110

101010000010111

1111111100011111

1110111

1110111

1110111

UTF-8方案如下:

11100100

10111011      今         (111 是标识, 10也是标识  今---------> 00100111011001010)

10001010                

 

11100101      

10100100      .

10101001      .

              .

11100100

10111101

10100000

 

11100101

10010000

10000011

11100100

10111010

10000110

11100101

10010000

10010111

11101111

10111100

10011111

 

1110111

1110111            

1110111

经典案例:将字符串写到文件:

RandomAccessFile raf=new ...?

       String str="你今天吃了吗?"

byte[] buf=str.getByte("UTF-8");

raf.write(buf);

     raf.close();

##############

RandomAccessFile raf=new ...?

byte[] buf=new buty[200];

//从文件raf中读取多个byte填充到buf数组中,返回值m表示填充个数

int n=raf.read(buf);

SYSTEM.OUT.PRITBLN(n);

String str=new String(buf,0,n,"utf-8");

//n 表示,200个字节中前n个是有效的。

System.our.pritnln(str);

raf.close();

 

编码测试:

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.RandomAccessFile;

import java.util.Random;

 

public class Demo1 {

public static void main(String[] args) throws IOException {


RandomAccessFile raf=new RandomAccessFile("demo", "rw");

byte[] buf=new byte[200];

int n=raf.read(buf);

String str=new String(buf,0,n,"utf-8");

System.out.println(str);

raf.close();

}

 

}

 

############控制文件读写位置

getFilePointer seek

############总结:

RandomAccessFile 总结

        1 可操作文件内容

2 可以任意移动文件指针 读写文件

3 每次读写1byte

4 提供了基本数据类型 读写方法

测试代码:

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.RandomAccessFile;

import java.util.Random;

 

public class Demo1 {

public static void main(String[] args) throws IOException, Exception {

RandomAccessFile raf=new RandomAccessFile("aa", "rw");

raf.write(25);

System.out.println(raf.getFilePointer());//跳到1

raf.writeInt(12345678);

System.out.println(raf.getFilePointer());//跳到5

//

raf.seek(1);//跳到int 数据开始的位置

int m=raf.readInt();

System.out.println(m);

System.out.println(raf.getFilePointer());

raf.close();

}

 

}

缺点:没有提供更复杂的读写方法

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值