跳转到内容

数字电路/表示

来自维基教科书,开放的世界,开放的书籍

数量与数字

[编辑 | 编辑源代码]

必须区分“数量”和“数字”。数量仅仅是某种“东西”的多少;五个苹果、三磅和一辆汽车都是不同事物的数量。数量可以用许多不同的表示方式来表示。例如,纸上的刻度线、绳子上的珠子或口袋里的石头都可以表示某种东西的数量。最常见的表示方式之一是十进制(或“基数-10”)数字,它由 10 位数字组成,从 0 到 9。当需要计算超过 9 个物体时,我们会在其中创建一个新的列,并在其中写 1(表示 10 个组),然后继续从那里计数。

然而,计算机不能以十进制方式计数。计算机硬件使用一种系统,其中值在内部以一系列电压差来表示。例如,在大多数计算机中,+5V 电荷表示为“1”位,而 0V 值表示为“0”位。不可能有其他位!因此,计算机必须使用一个只有两位数字(0 和 1)的编号系统:“二进制”或“基数-2”编号系统。

二进制数

[编辑 | 编辑源代码]

最初,许多学生难以理解二进制数系统。从十进制数开始可能会有所帮助,因为十进制数更熟悉。可以使用“展开表示法”来写像 1234 这样的数字,以便显示每个位置的值。

注意,每个数字都乘以 10 的连续幂,因为这是一个十进制数或基数-10 系统。“个位”数字(示例中的“4”)乘以,或“1”。“个位”数字左侧的每个数字都乘以 10 的下一个更高幂,并将该结果加到前一个值。

现在,对二进制数做同样的事情;但由于这是一个“基数-2”的数字,所以用 2 的幂替换 10 的幂。

下标表示基数。请注意,在以上等式中

二进制数与它们等效的十进制数相同,只是表示给定数量的不同方式。简单地说,您有 还是 个苹果,您仍然可以做馅饼。

术语进制数的缩写。每一位都是一个二进制值:1 或 0。计算机通常将 1 表示为正电压(5 伏或 3.3 伏是常见值),并将 0 表示为 0 伏。

最高有效位和最低有效位

[编辑 | 编辑源代码]

在十进制数 48723 中,“4” 位代表 10 的最大幂(或 ),而数字 3 代表 10 的最小幂 ()。因此,在这个数字中,4 是最高有效位,而 3 是最低有效位。考虑一个婚宴上,一位承办商需要准备 156 餐。如果承办商在最低有效位犯错,不小心做成了 157 餐,这不是什么大问题。但是,如果承办商在最高有效位 1 上犯错,做了 256 餐,那可就是大问题了!

现在,考虑一个二进制数:101011。最高有效位 (MSB) 是最左边的位,因为它代表 2 的最大幂 ()。最低有效位 (LSB) 是最右边的位,代表 2 的最小幂 ()。

请注意,MSB 和 LSB 与其他科学领域使用的“有效数字”概念不同。十进制数 123000 只有 3 位有效数字,但最高有效位是 1(最左边的数字),最低有效位是 0(最右边的数字)。

标准大小

[edit | edit source]
摘要
名称 长度/位
1
字节 4
字节 8
16
双字 32
四字 64
机器字 取决于
字节
一个字节是 4 位长。字节可以保存从 0 到 15(十进制)的值。
字节
一个字节是 8 位长。字节可以保存从 0 到 255(十进制)的值。
一个字是 16 位,或 2 个字节长。字可以保存从 0 到 65535(十进制)的值。偶尔会混淆这个定义和“机器字”的定义。请参见下面的机器字。
双字
一个双字是 2 个字长,或 4 个字节长。它们也称为“双字”。双字也称为 32 位长。因此,32 位计算机操作的是双字大小的数据。
四字
一个四字是 2 个双字长,4 个字长,8 个字节长。它们也称为“四字”。四字是 64 位长,因此是 64 位计算机中的默认数据大小。
机器字
机器字是给定机器的标准数据大小的长度。例如,32 位计算机有一个 32 位机器字。同样,64 位计算机有一个 64 位机器字。有时“机器字”一词会简称为“字”,导致人们不清楚我们指的是常规“字”还是机器字。

负数

[edit | edit source]

似乎在二进制中创建负数,读者只需要在数字前面加上“–”号就可以了。例如,二进制数 1101 可以简单地写成“–1101”来变成负数。这看起来一切都好,直到你意识到计算机和数字电路不理解减号。数字电路只有位,因此必须使用位来区分正数和负数。考虑到这一点,有许多不同的方案用于使二进制数变为负数或正数:符号位和幅度、反码和补码。

符号位和幅度

[edit | edit source]

符号位和幅度方案中,给定二进制数的 MSB 用作“标志”,用于确定该数是正数还是负数。如果 MSB = 0,则该数为正数,如果 MSB = 1,则该数为负数。这种方案看起来非常简单,除了一个简单的事实:在这种方案下,数字的运算非常困难。假设我们有 2 个字节:1001 和 0111。在符号位和幅度下,我们可以将它们翻译成:-001 和 +111。那么,在十进制中,这些数字分别是 –1 和 +7。

当我们将它们加在一起时,–1 + 7 = 6 的和应该是我们得到的值。但是

 001
+111
----
 000

这不对。我们需要的是一个决策结构,来确定 MSB 是否被设置,如果被设置,则减去,如果没有被设置,则加上。这很麻烦,因此符号位和幅度没有被使用。

反码

[edit | edit source]

现在让我们检查一下一种方案,其中我们将负数定义为正数的逻辑反转。我们将使用相同的“!”运算符来表示对多个位的逻辑反转。例如,!001100 = 110011。110011 是 51 的二进制表示,而 001100 是 12 的二进制表示。但在这种情况下,我们说 001100 = –110011,或者 110011(二进制)= -12 十进制。让我们再次执行加法

 001100 (12)
+110011 (-12)
-------
 111111

我们可以看到,如果我们反转 0000002,我们得到的值是 1111112。因此,1111112 是负零!负零到底是什么?事实证明,在这种方案中,正零和负零是相同的。

然而,反码表示法存在问题,因为它对零有两种表示:全 0 位或全 1 位。除了笨拙之外,这还会在我们要快速检查一个数是否为零时造成问题。这是一个非常常见的操作,我们希望它很简单,因此我们创建了一种新的表示方法,补码。

补码

[edit | edit source]

补码是一种数字表示法,它与反码非常相似。我们使用以下公式找到数 X 的负数

-X = !X + 1

让我们举个例子。如果我们有二进制数 11001(十进制为 25),我们想找到 -25 的补码表示,我们遵循两个步骤

  1. 反转数字
    11001 → 00110
  2. 加 1
    00110 + 1 = 00111

因此,–11001 = 00111。让我们做一个小加法

 11001
+00111
------
 00000

现在,将两个 MSB 加在一起会产生进位,但这毕竟是数字逻辑,所以我们丢弃进位。重要的是要记住,数字电路的位数是有限的,任何额外的位都会被丢弃。

大多数现代计算机使用补码。

下图显示了这些系统对所有 4 位组合的表示

带符号的 vs 无符号的

[edit | edit source]

要记住的一件重要的事情是,计算机是愚蠢的。计算机不知道一组给定的位表示的是带符号数还是无符号数(或者,就此而言,还有其他数据对象)。因此,程序员(或程序员信赖的编译器)必须为我们跟踪这些数据。考虑位模式 100110

  • 无符号:38(十进制)
  • 符号位和幅度:-6
  • 反码:-25
  • 补码:-26

看看我们使用的表示方式如何改变数字的值!重要的是要理解,位就是位,计算机不知道位代表什么。电路设计者和程序员负责跟踪数字的含义。

字符数据

[编辑 | 编辑源代码]

我们已经了解了二进制数如何表示无符号值以及如何使用各种方案表示负数。但是现在我们必须问自己,二进制数如何表示其他形式的数据,比如文本字符?答案是存在将二进制数据转换为字符的不同方案。每个方案都像一个映射,将特定的位模式转换为特定的字符。有三种流行的方案:ASCII、UNICODE 和 EBCDIC。

ASCII 代码(美国信息交换标准代码)是将位映射到字符的最常见代码。ASCII 仅使用 7 位,但由于计算机一次只能处理 8 位字节,因此 ASCII 字符的第 8 位(MSB)未用。ASCII 代码 0-31 是“控制代码”,这些代码是不能打印到屏幕上的字符,计算机使用它们来处理某些操作。代码 32 是一个空格(按空格键)。字符 '1' 的字符代码是 49,'2' 是 50,等等... 注意在 ASCII 中 '2' = '1' + 1(字符 1 加上整数 1)。这对许多人来说一开始很难理解,所以如果你感到困惑,不要担心。

大写字母从 'A' = 65 到 'Z' = 90 开始。小写字母从 'a' = 97 到 'z' = 122 开始。

几乎所有其他 ASCII 代码都是不同的标点符号。

扩展 ASCII

[编辑 | 编辑源代码]

由于计算机使用字节大小的数据,因此让 ASCII 只包含 7 位数据(最多 128 个字符代码)没有意义。因此,许多公司将额外的位合并到“扩展 ASCII”代码集中。这些扩展集最多可以使用 256 个字符。前 128 个字符是原始 ASCII 字符,但接下来的 128 个字符是平台定义的。每个计算机制造商都可以定义自己的字符来填充最后 128 个位置。

当计算机开始在世界各地普及时,计算机开始使用其他语言。很快,每个国家都有自己的字符代码集来表示自己的字母。重要的是要记住,世界上有些字母表有超过 256 个字符!因此,提出了 UNICODE 标准。UNICODE 有许多不同的表示形式。其中一些使用 2 字节字符,而另一些使用不同的表示形式。UNICODE 集的前 128 个字符是原始 ASCII 字符。

有关 UNICODE 的更深入讨论,请参见 此网站

EBCDIC(扩展二进制编码十进制交换码)是最初由 IBM 提出的字符代码,但后来被 ASCII 代替。然而,IBM 仍然在其一些超级计算机、大型机和服务器系统中使用 EBCDIC。

八进制

[编辑 | 编辑源代码]

八进制与十进制和二进制类似,一旦一列“满”,就会移到下一列。它使用数字 0−7 作为数字,并且由于有可用的二进制倍数(8=23)的数字,它有一个有用的特性,即在八进制和二进制数之间进行转换很容易。考虑二进制数:101110000。要将此数字转换为八进制,我们首先必须将其分成 3 位一组:101、110、000。然后我们只需将每一位的值加起来

然后我们将所有八进制数字串在一起

1011100002 = 5608.

十六进制

[编辑 | 编辑源代码]

十六进制是一种非常常见的数数据表示方式。它比八进制更常见,因为它每个数字代表四个二进制数字,并且许多数字电路使用 4 的倍数作为其数据宽度。

十六进制使用 16 为基数。但是,存在一个困难,因为它需要 16 位数字,而常见的十进制数系统只有十位数字可以使用(0 到 9)。因此,为了拥有足够的数字可以使用,我们使用字母 A 到 F,以及数字 0-9。单位列满后,我们将移到“16 位”列,就像二进制和十进制一样。

十六进制 十进制 八进制 二进制
0 0 0 0000
1 1 1 0001
2 2 2 0010
3 3 3 0011
4 4 4 0100
5 5 5 0101
6 6 6 0110
7 7 7 0111
8 8 10 1000
9 9 11 1001
A 10 12 1010
B 11 13 1011
C 12 14 1100
D 13 15 1101
E 14 16 1110
F 15 17 1111

十六进制符号

[编辑 | 编辑源代码]

根据您正在阅读的源代码,十六进制可能会用以下几种方式之一表示

  • 0xaa11: ANSI C 符号。前缀0x指示剩余的数字将被解释为十六进制。例如,0x1000,等于十进制的 4096。
  • \xaa11: “C 字符串”符号。
  • 0aa11h: 典型的汇编语言符号,由h后缀指示。前导0(零)确保汇编器不会错误地将数字解释为标签或符号。
  • $aa11: 另一种常见的汇编语言符号,广泛用于 6502/65816 汇编语言编程。
  • #AA11: BASIC 符号。
  • $aa11$: 商业 BASIC 符号。
  • aa1116: 数学符号,下标表示数字基数。
  • 16#AA11#: VHDL 符号,用于表示数字。
  • x"AA11": VHDL 表示一个 16 位位的数组。
  • 16'hAA11: Verilog 表示法,其中“16”是总位数。

可以使用大写和小写字母。在 Linux、UNIX 或 C 环境中通常首选小写字母,而在大型机或 COBOL 环境中通常首选大写字母。

进一步阅读

[编辑 | 编辑源代码]
华夏公益教科书