有关于反码补码的问题,以及很多初学者会经常问道 -128 的反码和补码的问题

1.       原码反码补码概念以及转换

 

1.1    原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值,例如:

原码:[+1]0000 0001

原码:[-1]1000 0001

1.2    反码

正数的反码是其本身

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

原码:[+1]0000 0001 反码:0000 0001

原码:[-1]1000 0001 反码:1111 1110

1.3    补码

正数的补码就是其本身

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

原码:[+1]0000 0001 反码:0000 0001 补码:0000 0001

原码:[-1]1000 0001 反码:1111 1110 补码:1111 1111

#include <stdio.h>

 

int main(int argc, const char * argv[])

{

//  其实数据存储在内存中都是存储的二进制

//  二进制又可以分为原码、反码、补码

//  其实最终存储在内存中的是补码

//    int4个字节 1个字节8所以整形就站 32

    int num = 12;

    /*

//     12的二进制

     12在内存中存储的是它的补码

     00000000  00000000 00000000 00001100

     正数:(三码相同)正数的原码就是它反码,也是它的补码

    

     -12

     二进制的最高位我们称之为符号位

     如果符号位是0代表是一个正数,

     如果符号位是1代表是一个负数

    

     10000000  00000000 00000000 00001100 (-12的原码)

     11111111  11111111 11111111 11110011(反码, 符号位不变其它位取反)

    

     11111111  11111111 11111111 11110011

    +00000000  00000000 00000000 00000001

     _____________________________________________

     11111111  11111111 11111111 11110100(补码 , 反码+1)

    

     结论:无论正数负数在内存中存储的都是补码

 

     11111111  11111111 11111111 11110101 (补码)

    -00000000  00000000 00000000 00000001  (-1)

     _____________________________________________

     11111111  11111111 11111111 11110100 (反码)

     10000000  00000000 00000000 00001011

    

     */

    printf("%d\n", 0b11111111111111111111111111110101);

    return 0;

}

 


 

2.       为什么要引入反码、补码?

 

 主要是为了方便计算机计算,因为计算机制作加法计算,没有减法计算

     1、由于最高为是符号位,如果是0就代表正数,如果是1就代表是负数

     2、如果直接存储原码,计算机在计算的时候还需要判断最高位才能计算,效率较低

     3、为了方便计算机计算,所以有了反码和补码,有了反码和补码之后,以后计算机就不需要判断最高位,直接计算即可(计算机只做加法计算)

       1 + 1

       0001

     + 0001

     ————————

       0010 ==2

       1 - 1 == 1 + -1==计算机只会做加法

        0000 0001 原码

     + 1000 0001 原码

     ————————————————

       1000 0010 == -2

    

     1 - 1 == 1 + -1== 计算机只会做加法

       0000 0001 原码(+1反码)

     + 1111 1110 反码

     ————————————————

       1111 1111 ==  反码

     将计算出来的反码转为原码,再见原码转换为十进制

     1000 0000 == 原码 == -0

    

     1 - 1 == 1 + -1== 计算机只会做加法

       0000 0001 +1补码)

     + 1111 1110 -1补码)

     ——————————————————

     1 0000 0000 == 0 补码

最后补充一点

这样0[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128: (-1) + (-127) = [1000 0001] + [1111 1111] = [1111 1111] + [1000 0001] = [1000 0000]

-1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补码就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(-128的补码表示[1000 0000]补算出来的原码是[0000 0000], 这是不正确的)

有人会问 10000000这个补码表示的哪个数的补码呢? 其实这是一个规定,这个数表示的是-128所以n位补码能表示的范围是 -2^(n-1)2^(n-1)-1 n位原码能表示的数多一个

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值