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

本文详细介绍了计算机中二进制表示、不同进制之间的转换及补码的概念。通过实例解析了正负数的源码、反码、补码的区别,并展示了二进制与十进制间的转换过程。

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

1)概念知识:

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

  1.  二进制: o,1, 满2进1,以0b/B开头
  2. 十进制: 0-9 满10进1,平常通用。
  3. 八进制:0-7,满8进1,以0开头
  4. 十六进制:0-9 a-f  满16进1, 以0x开头,不分大小写。

 

 

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

 

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

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

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

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

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

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

 

 

 

  先看下如下代码:

 

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)底层如何转换

 

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

 

2.1)data&0xff

 

看下如何转换的:

2.1)采用二进制 转换

  data的二进制:100010011010      

 0xff的二进制:        11111111

结果为:   000010011010 如上a的值:

 

但是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

    

 

 

 

 

 

### 源码补码反码的概念及用法 #### 一、源码(Sign-Magnitude) 源码是一种简单的二进制表示方法,其中最高位作为符号位,其余位用来表示数值的绝对值。如果符号位为`0`,则该数为正;如果符号位为`1`,则该数为负。 例如,在8位系统中: - `+5` 的源码表示为:`0000 0101`[^1]。 - `-5` 的源码表示为:`1000 0101`[^1]。 这种表示方法的优点在于直观易懂,缺点是存在两个零(`+0` `-0`),这可能导致计算复杂化。 --- #### 二、反码(One's Complement) 反码是对源码的一种改进形式。对于正数,其反码源码相同;而对于负数,则将其源码的数值部分逐位取反即可得到反码。 例如,在8位系统中: - `+5` 的反码表示为:`0000 0101`[^4]。 - `-5` 的反码表示为:`1111 1010`。 需要注意的是,反码同样存在两个零的情况(`+0` `-0`),这也使得它在实际应用中不如补码广泛使用。 --- #### 三、补码(Two's Complement) 补码是最常用的二进制表示方法之一,尤其适用于计算机内部的数据存储运算。对于正数,其补码源码相同;而对于负数,则先求得其反码后再加`1`即可获得补码。 例如,在8位系统中: - `+5` 的补码表示为:`0000 0101`。 - `-5` 的补码表示为:`1111 1011`。 补码的优势在于能够唯一地表示零,并且简化了加减法操作的过程。此外,通过补码可以直接实现模运算,从而避免复杂的逻辑判断。 --- #### 四、转换规则总结 以下是三种编码方式之间相互转换的具体规则: 1. **源码反码** 对于正数,保持不变;对于负数,将数值部分逐位取反。 2. **反码补码** 对于正数,保持不变;对于负数,对其反码加`1`。 3. **补码源码** 如果已知某数的补码为正,则直接读作源码;如果是负数,则需先对该补码减去`1`再逐位取反,最后加上符号位。 --- #### 五、计算机中的具体表示 以常见的32位有符号整型为例,采用补码表示时可覆盖范围为 `[−2³¹, 2³¹ − 1]`[^3]。这是因为第一位被分配给符号位,同时利用补码特性还能额外容纳一个最小值(即`−2³¹`)。 ```c #include <stdio.h> int main() { int num = -5; printf("The binary representation of %d is: ", num); // 手动打印补码形式 unsigned n = *(unsigned *)&num; // 将 int 类型强制转为 unsigned for (int i = sizeof(n)*8 - 1; i >= 0; --i) { putchar(((n >> i) & 1) ? '1' : '0'); } return 0; } ``` 此程序展示了如何查看任意整数在其内存中的补码表现形式。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值