io流和源码,补码,反码相关

最近做canal 其中parse 模块的driver 里面二进制 ,十六进制,io流转换,不是很懂,就亲自己实践一下:

1)先看下概念知识:

      一个数在计算机中的二进制表示形式,  叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1

       比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 ,那么,这里的 00000011 和  10000011 就是机器数。

      因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而        不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。

    源码:原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

    反码:正数的反码是其本身  负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

    补码: 正数的补码就是其本身    负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

    总结:正数 :源码,反码,补码都是本身

             负数: 反码为符号位不变,其余取反,补码为反码+1

io流和源码,补码,反码相关


io流和源码,补码,反码相关


io流和源码,补码,反码相关


  先看下如下代码:

public static void main(String[] args) {
    int data=2202;
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    out.write((byte) (data & 0xFF));
    out.write((byte) (data >>> 8));
    out.write((byte) (data >>> 16));
    out.write((byte) (data >>> 24));

    System.out.println("data的二进制:"+Integer.toBinaryString(data));
    System.out.println("=======================================");
    int a =data & 0xFF;
    System.out.println("a的二进制:"+Integer.toBinaryString(a));


}

result:

data的二进制:100010011010
=======================================

a的二进制:10011010

2)底层如何转换

io流和源码,补码,反码相关

buf为31个默认初始0,count为0

2.1)data&0xff

io流和源码,补码,反码相关


看下如何转换的:

2.1)采用二进制 转换

  data的二进制:100010011010      

 0xff的二进制:        11111111

结果为:   000010011010 如上a的值:

io流和源码,补码,反码相关


但是a的二进制是10011010  那debug 为何为-102?

 以上运算,我们计算的结果为计算机的逻辑运算,但是计算机存放二进制,是以补码存放的, 所以 10011010的补码为其反码取反+1 也就是:

        1001 1010 

取反:符号位不变

         1110 0101

+1

         1110 0110

  看下1110 0110 的十进制是多少:

   108 64 32 16 8 4 2 1 

            1   1  0 0 1 1 0

 结果为:

-102