《编译原理》复习笔记——原码、反码、补码

/ 0评 / 0

概念

原码:符号位+真值,符号位0代表正,1代表负。

反码:正数的反码是其本身,负数的反码是符号位以外的各位取反。

补码:正数的补码是其本身,负数的补码是反码加1(符号位也参与运算,这个不用太在意,因为只有求负零的补码才会影响到符号位,而正零和负零是一样的)

取反相当于什么?

我们知道,在计算机中无论加减都是按照其补码相加的和求结果,因为2-1相当于2+(-1),那么为什么用补码就能实现呢?原理是什么?

先弄清取反相当于什么运算。例子:1010取反是0101,101110取反是010001。

我的理解方法有两种,第一种:对一个数取反就相当于用“全1”减这个数,“全1”就是各个位都是1。例子:1010取反是0101,1111-1010=0101。

第二种:可以按十进制来理解,因为还没搞懂LaTeX在WordPress中怎么使用,就先手写表示吧。

两种方法从数值上来看都是:当前位数能表示的最大值减去当前数。

原理

一句话简单理解就是:用0~10表示-5~5

实际在二进制中,如4位二进制,就是用0~15表示-7~7,其中0~7还是表示0~7,8~15表示-7~-1

原码运算3-5=-2,补码中实际是3+10=13,补码13换算成原码就是-2

可能还是没讲清楚。。。。表达能力不好

相关问题

在知乎上看到一个问题:

C语言十进制转八进制负数转法出现问题?

#include <stdio.h>
void main()
{
    int a=-7;
    printf("a1=%o,a2=%5o\n",a,a);
}

运行结果是37777777771

这里的关键点是%o表示的是打印无符号八进制数,即unsigned int。

但37777777771是怎么算出来的,我们分析一下计算机内部的实际数据。

int用4字节保存,即32位,第一位是符号位。

-7在内存中的保存形式(补码):

原码:1000 0000 0000 0000 0000 0000 0000 0111

反码:1111 1111 1111 1111 1111 1111 1111 1000

补码:1111 1111 1111 1111 1111 1111 1111 1001

如果把这个补码当作unsigned int来输出(原反补码都一样)

(0)11 111 111 111 111 111 111 111 111 111 001 最前面补一个零方便计算

上面这个数按八进制换算成十进制就是37777777771

发表评论

电子邮件地址不会被公开。 必填项已用*标注