编程小技巧

    返回首页    发表留言
本文作者:李德强
          技巧九:补码原理
 
 

        今天要跟大家分享的小技巧是关于补码的, 这部分内容其实我已经在《C语言深处》里讲述过了,但我觉得这是一个非常重要知识点,所以再把它单独拿出来跟大家分享一下:

        在计算机中数通常采用补码的形式来表示。正数和0的补码为其本身,负数的补码为其绝对值取反再加1。

10进制数 绝对值 原码(不包括符号位) 反码(不包括符号位) 补码(不包括符号位) 实际补码(包括符号位)
-3 3 000 0011 111 1100 111 1101 1111 1101
-23 23 001 0111 110 1000 110 1001 1110 1001
-127 127 111 1111 000 0000 000 0001 1000 0001

 

        下面再来看一个非常有趣的赋值问题:

#include <stdio.h>

int main(int argc, char **args)
{
        char i = 0;
        short j = 129;
        i = j;
        printf("%d\n", i);

        return 0;
}

        运行结果为:

-127

        结果出乎我们的意料,但却是正确的运行结果。来看一下这个赋值运算的原理:

        上面例子中char i的值为-127,其补码为1000 0001正好是short j的129的原码。所以char i = 129;的结果是-127。

        负数在计算机中通常以补码(反码+1)的形式表示,那为什么要采用反码+1来表示负数呢?我们来看一下9的补码为0000 1001(正数的补码是其原码)。在计算机中为了能让CPU对所有的数,无论是正数还是负数都能够快速的进行正确的加减运算,例如要让CPU能够快速的识别并运行9 + (-9) = 0这样的运算法则。也就是说让0000 1001加上一个数(-9)能让结果快速的变为0,这个过程分为两步:

        1.让9加上其本身的反码,即得到一个全1的结果:

                0000 1001
             + 1111 0110 
                1111 1111

        2.在全1的结果基础上再加1,即出现多米诺骨牌效应,所有位均为0,第9个bit位的1溢出,所以结果为0:

                1111 1111
             + 0000 0001 
                0000 0000

        把上面两步的运算合并成一步运算,即一个正数加上其反码+1结果为0,为了能让CPU能够快速的计算正负数的加减法,所以负数通常采用“补码”的形式来表示。

        再来看看两个负数的加法:

        (-9) + (-7) = -16

        -9的补码为1111 0111,-7的补码为1111 1001,两个负数的加法结果为:

                1111 0111
             + 1111 1001​ 
                1111 0000

        1111 0000取其补码(符号位不变)的结果为1001 0000 = -16

        补码是为了便于CPU执行数的加减法运算,无论是正数还是负数CPU都可以快速识别和计算,并很好的通过多米诺骨牌效应达到正确的计算结果。

 

        今天的小技巧你学会了吗?

 

 

    返回首页    返回顶部
  看不清?点击刷新

 

  Copyright © 2015-2018 问渠网 辽ICP备15013245号