原码, 反码, 补码 详解
机器数与真值
机器数
- 一个数在计算机中的二进制表示形式, 叫做这个数的机器数;
- 机器数是带符号的, 使用最高位为符号位, 正数为0, 负数为1;
- 如: +3:0000 0011; -3:1000 0011; 这里的二进制就是机器数;
真值
- 因为第一位为符号位, 所以机器数的形式值就不等于真正的数值;
- 如:1000 0011, 其最高位1代表负, 其真正数值是-3而不是形式值131;
- 将符号位的机器数对应的真正的数值称为机器数的真值;
- 如: 0000 0001的真值是: +1; 1000 0001的真值是: -1;
==原码, 反码, 补码的基础概念和计算方法==
原码
- 原码就是符号位加上真值的绝对值
- 第一位为符号位,所以8位二进制的范围为: [1111 111, 0111 111]; [-127, 127]
- 上面的范围缺-128? 后面解释.
- 最符合人脑的方式;
反码
- 正数的反码是其本身;
负数的反码是在其反码的基础上, 符号位不变, 其余位取反:如
- [+1] = [0000 0001]原 = [0000 0001]反
- [-1] = [1000 0001]原 = [1111 1110]反
如果一个反码表示负数, 人脑无法直接观看;
补码
对于正数都是一样的,所以忽略;
对于负数,不同, 为什么会存在呢?
- 对于人脑, 可以知道第一位是符号位, 在计算的时候会根据符号位,选择对真值区域的加减;
- 对于计算机,加减乘除已经是最基础的运算, 要设计的尽量简单, 计算机辨别”符号位”显然会让基础电路 变的复杂, 于是人们开始考虑让符号位也参与运算的方法;
- 根据运算规则, 1-1 = 1 + (-1) = 0; 如果机器只有加法没有减法, 计算机运算的设计就更简单了;
人们继续探索将符号位参与运算, 并且只保留加法的方法:
- 1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [1000 0010]原 = -2 如果用原码表示,让符号位参与运算, 显然对于减法来说, 结果不正确, 这也就是计算机中不使用 原码表示一个数, 为了解决原码做减法的问题, 出现了反码;
- 1 - 1 = 1 + (-1) = [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0 发现使用反码计算减法, 结果的真值部分是正确的, 但是确出现了-0, 而且-0是没有用, 并且会有 [0000 0000]原 和 [1000 0000]原 俩个编码表示0; 于是出现了补码, 解决了0的符号问题, 以及俩个编码的问题,
- 1-1 = 1 + (-1) = [0000 0001]补+[1111 1111]补 = [0000 0000]补 = 0 (-1)+(-127) = [1111 1111]补 + [1000 0001]补 = [1000 0000]补 = -128; -1-127的结果是-128, 在用补码运算的结果中, [1000 0000]补 就是-128, 实际就是-0的补码, 所以-128并没有原码和反码表示.
使用补码, 不仅仅修复了0的符号以及存在俩个编码的问题, 而且还能够多表示一个最低数, 这就是为什么8位二进制, 使用原码或反码表示的范围是[-127, 127], 而使用补码表示的范围是[-128, 127];
- 机器使用补码, 所以对于编程中常用到的32位int类型, 可以表示范围: [-2^31, 2^31 -1], 因为第一位表示符号位,使用补码表示时可以多保存一个最小值;
原码,反码, 补码 再深入
参考网址:博客园已转载
大端小端
- 小端: 低位字节存放在内存的低地址端, 高位字节存放在内存的高地址端;
- 大端: 高位字节存放在内存的低地址端, 低位字节存放在内存的低地址端;
- 网络字节序: 大端模式;
1 | 如: |
1 | // 算法 |