zoukankan      html  css  js  c++  java
  • 重要:原码、反码、补码...

    涉及计算机运算中的底层运算,所以一步步来。

    一、pascal中的整数类型

    Type           Range                                                 Size in bytes
    Byte           0 .. 255                                              1
    Shortint       -128 .. 127                                           1
    Word           0 .. 65535                                            2
    Integer        -32768 .. 32767                                       2
    Longword       0 .. 4294967295                                       4
    Longint        -2147483648 .. 2147483647                             4
    QWord          0 .. 18446744073709551615                             8
    Int64          -9223372036854775808 .. 9223372036854775807           8
     
    整数有占1、2、4、8字节的,分为无符号与有符号。有符号的整数比无符号的常用。
    有符号的整数与内存的约定是补码的形式。数据在内存中以补码形式存储,运算也以补码形式运算,运算结果也是补码。
    int64与qword不是顺序类型,不能作为循环控制变量。
    word经常被翻译成“字”,是占两个字节的无符号整数类型。
    Dword是longword的别名,意思是double word,两个字是4字节。
    Qword是四个字。带word的都是些无符号整数

    运行以下程序,加深印象:

    program test;
    begin
      writeln(sizeof(byte));     //1
      writeln(sizeof(shortint)); //1
      writeln(sizeof(word));     //2
      writeln(sizeof(integer));  //2
      writeln(sizeof(longword)); //4
      writeln(sizeof(longint));  //4
      writeln(sizeof(qword));    //8
      writeln(sizeof(int64));    //8
      writeln(MaxLongint); //取得longint的最大整数值
    end.
    View Code

    二、处理负值时,采用补码

    P44 补码中“补”的含义,有关同余定理。

    初看有点难理解,说清楚了并不难理解。(以下省略五百字,上课时再说明)

    这个代码,有助于理解P45 图2

    //45
    program test;
    var
      i:longint;
      b:shortint;
    begin
      b:=7;
      for i:=1 to 16 do begin
        write( b:4, space(4) );
        writeln( binstr(b,4) );
        dec(b);
      end;
    end.
    View Code

    三、正数与负数的转换方法

    正数转换成负数:

    //47-1
    program test;
    var
      i:shortint;
    begin
      i:=%00000001; //以二进制形式输入变量值
      writeln( i ); //以十进制形式输出
      writeln( binstr(i,8) ); //以二进制形式输出
      i:=not(i); //取反,即得到 one's complement,或称一补数
      writeln( binstr(i,8) ); //一补数以二进制形式输出
      inc(i); // +1,加一后,得到 two's complement,或称二补数,就是补码
      writeln( i ); //以十进制形式输出
      writeln( binstr(i,8) ); //以二进制形式输出
    end.
    View Code

    负数转换成正数:

    //47-2
    program test;
    var
      i:shortint;
    begin
      i:=%11111100; //这是个负数
      writeln( i ); //以十进制形式输出
      writeln( binstr(i,8) ); //以二进制形式输出
      i:=not(i); //取反,即得到 one's complement,或称一补数
      writeln( binstr(i,8) ); //一补数以二进制形式输出
      inc(i); // +1,加一后,得到 two's complement,或称二补数,就是补码
      writeln( i ); //以十进制形式输出
      writeln( binstr(i,8) ); //以二进制形式输出
    end.
    View Code

    有个现象观察到没有?取反加1,可以不断进行下去。。

    //47-2
    program test;
    var
      i:shortint;
    begin
      i:=%11111100; //这是个负数
      writeln( i ); //以十进制形式输出
      writeln( binstr(i,8) ); //以二进制形式输出
      i:=not(i); //取反,即得到 one's complement,或称一补数
      writeln( binstr(i,8) ); //一补数以二进制形式输出
      inc(i); // +1,加一后,得到 two's complement,或称二补数,就是补码
      writeln( i ); //以十进制形式输出
      writeln( binstr(i,8) ); //以二进制形式输出
      i:=not(i)+1; writeln( i );
      i:=not(i)+1; writeln( i );
      i:=not(i)+1; writeln( i );
      i:=not(i)+1; writeln( i );
      //...
    end.
    View Code

    四、原码、反码、补码、移码、负补

    看着头晕不?其实相当简单。

    1、原码

    事先确定数据的位长,即二进制的位数。因为内存以字节为单位,一字节为八位,所以位长是八的倍数。

    当不够位长时,前面用0补足。但如果是负数,最高位用1补足。

    其中最高位为符号位:正数为0,负数为1。

    以位长为八为例子:

    +11 的原码为:0000 0011

    -11 的原码为: 1000 0011

    2、反码

    在原码的基础上,最高一位为符号位,不变,其余各位取反。所谓取反,就是not(...),即0成1,1成0。

    +11 的反码为:0000 0011

    -11 的反码为:1111 1100

    3、补码

    在反码的基础上,加一,就得到补码。

    +11 的补码为:0000 0011

    -11 的补码为:1111 1101

    可以看到,正数的原、反、补码都一样。

    4、移码

    移码最简单了,不管正负数,只要将其补码的符号位取反即可。

    +11 的移码为:1000 0011

    -11 的移码为:0111 1101

    5、负补

    对补码的每一位(包括符号位)求反,然后最低位加一。

    +11 的补码为:0000 0011,对每一位求反,为:1111 1100,最低位加一,为:1111 1101

    -11 的补码为:1111 1101,对第一位求反,为:0000 0010,最低位加一,为:0000 0011

    将一个数的补码,与负补码加起来,你会发现什么?

    请看代码,仅以负数举例:

    program test;
    var
      i,j,k:shortint;
    begin
      i:=-%11; //二进制的 -11
      writeln( binstr(i,8) ); //以二进制形式输出。
      //观察输出,可以发现,内存中,以补码的形式储存数据
      j:=i xor %10000000;
      writeln( binstr(j,8) ); //移码
      k:=not(i)+1;
      writeln( binstr(k,8) ); //负补码
      writeln( binstr(i+k,8) ); //补码+负补码,产生上溢
    end.
    View Code

    接下来,请看下一章:整数类型,如同时钟。

  • 相关阅读:
    PAT A1147 Heaps (30 分)——完全二叉树,层序遍历,后序遍历
    # 数字签名&数字证书
    # Doing homework again(贪心)
    # Tallest Cows(差分)
    # ACM奇淫技巧
    # 二维前缀和+差分
    # 费解的开关(二进制+递推+思维)
    # log对数Hash映射优化
    # 起床困难综合症(二进制枚举+按位求贡献)
    # 最短Hamilton路径(二进制状态压缩)
  • 原文地址:https://www.cnblogs.com/xin-le/p/3980931.html
Copyright © 2011-2022 走看看