为什么零被视为正号?

为什么零被视为正号?

以有符号整数或二进制数字表示

零被视为正号

1 被视为负号。

例如 :-

1000 0000 0000 0110 = -6 
0000 0000 0000 0110 =  6

但在脉冲形式中,1 被视为正,而 0 被视为中性。

         ---   ---   ---
         | |   | |   | |
---------   ---   ---   ---------

为什么?这背后有什么逻辑吗?

是否可以以相反的方式处理它,即 1 为正号,0 为负号

答案1

您最初的断言并不正确,对于绝大多数使用“二进制补码算法”的常见 CPU 架构来说并非如此。

在 2 的补码运算中,如果高位为 1,则表示负数;但如果高位为 0,则不表示正数。它表示非负。差异很微妙,但很重要。数字可能是零,也可能是正数。

在 2 的补码中,数字刻度如下所示 - 为简单起见,我将使用八位整数:

二进制 有符号 无符号
0111111111127127
01111110126126
 ...
00000011 3 3
00000010 2 2
00000001 1 1
00000000 0 0
11111111 -1 255
11111110 -2 254
 ...
10000010 -126 130
10000001 -127 129
10000000 -128 128

在这个系统中,要对一个数字取反(算术取反),也就是将其乘以 -1:首先取反所有位,然后加 1。因此,如果我们从 1 开始,然后取反所有位,我们将得到 11111110。加 1,我们得到 11111111。如上所述。请注意,如果我们再次执行此操作,我们将得到 00000001,正如我们应该得到的那样。

计算机使用这个系统是因为它使加法、减法等算术逻辑变得非常简单:相同的逻辑(简单的二进制加法器;你只需添加所有位,包括符号位)适用于有符号数和无符号数。请注意,在该范围内的任何数字上加 1 都会得到正确答案……溢出情况除外:如果你将数字解释为有符号的,则将 1 加到 127 上会得到 -128。但溢出和进位等通常由条件标志或异常捕获。

二进制补码的一个奇怪特点是负数比正数多一个……因为零既不是负数也不是正数。因此,使用带符号的八位,我们可以表示 -128,但不能表示 +128。+127 是最高正数。这不是什么大问题。

一些历史计算机(CDC 3000 和 6000 系列,以及一些旧的 Univac 大型机;我不知道当代的例子)已经使用“一的补码”。在一的补码中,要反转数字,只需翻转位。这会产生与上面几乎相同的比例,只是负数从 -127 变为... -0!没错,在一的补码机器中,有两个零:正零和负零。这使得算术通常更加复杂。负零通常会在某个时候转换为正数。

您可能认为它应该更像“有符号的幅度”,这类似于我们通常写数字的方式。例如 -2 将是 10000002。您会注意到,向其添加 1 并不能为您提供 -1 的正确有符号的幅度表示。相反,它会给出 -3。这使得算术变得更加复杂,这就是为什么它不被使用的原因。

答案2

这其实相当复杂。从某种程度上来说,答案是“因为我们需要某种标准”:如果你开发一个新系统,那么让它以与旧系统相同的方式运行要容易得多,这样你就可以更轻松地与旧系统交互。然而,在某些情况下,还有更深层次的原因。

在本文中,我将假设整数为 8 位。使用不同的位数时,原理应该相同。

电脉冲

这里只有两个值,我们称哪个为“零”,哪个为“一”并不重要。事实上,没有理由称它们为“零”和“一”。例如,USB 使用“J”和“K”,并且一些 USB 设备使用与其他设备相反的约定来实际传输信号。

整数编码

实际上,有几种方法可以对整数进行编码。您在问题中展示的方法称为“带符号的数值”。它与我们在日常生活中写数字的方式非常相似:我们可能有一个减号,然后我们写出数字。在这种情况下,减号(或加号)只是第一位的值。

但是,并非所有数字都是有符号的。如果我要对工厂今天生产的小部件数量进行编码,我想使用无符号数(除非我有时会销毁工厂中的小部件)。在这种情况下,让 表示0000 0110我当天生产了六个小部件才是合理的。

如果您同时使用有符号数和无符号数,那么如果它们之间的转换尽可能简单就好了。如果在两种情况下相同的位代表相同的数字,则转换会更容易,因此0000 0110即使我们使用有符号整数,我们也希望表示六。这导致前导1为负数,前导0为正数。

二进制补码

但是现在很少有系统真正使用有符号整数。有符号整数有许多问题,包括0000 00001000 0000表示同一件事(零)。相反,大多数系统使用所谓的“二进制补码”来表示有符号整数。它以相同的方式表示正数(以零为前导,其他位与无符号数相同),但以不同的方式表示负数。对于无符号的八位数,最高有效位是 128 位;对于二进制补码八位数,它是负 128 位。因此,1000 0000为负 128,1000 0001为负 128 + 1 = 负 127,一直到1111 1111,为负一。

这似乎是一种表示有符号整数的奇怪方法,但与更明显的有符号幅度相比,它有许多优点。首先,它解决了我之前提到的零有两种表示方法的问题。其次,您可以使用与添加无符号数相同的电路来添加数字,并且假设没有溢出(即使有溢出,也更容易处理),它将正确运行。有符号幅度则不然。

结论

有很多方法可以表示有符号数; 有符号幅度和二进制补码只是其中两种比较流行的方法。从某种意义上说,使用哪种方法并不重要;理论上,你可以发明你自己的方法(没有列出来)(或者只使用符号位反转的有符号幅度),并制造使用它的整台计算机。但这很可能不是一个好主意,因为如果你想与另一台计算机共享数据,你需要转换成不同的格式。我们最终可能会使用有符号幅度整数作为我们的标准(就像我们在浮点数字),那么对于大多数新计算机来说,最佳选择可能就是做同样的事情。但是,这种选择并不是完全随意的,有充分的理由让正整数使用前导零而不是前导一(例如与无符号数一致)。

答案3

这是一个任意的标准整数。查看较小的有符号字节,其中 00000000 到 01111111 被视为正整数,最高位在设置时使它们为负数,范围从 -127 到 127(基数为 10),零编码前导位设置或不设置。相同的位模式编码未签名数字 0 到 255,因此它只是一个让程序员能够理解其他人工作的标准。参见http://en.wikipedia.org/wiki/Signed_number_representations有关有符号数表示的信息。

你可以发明自己的有符号数标准,但这会导致混乱。在某些语言中,布尔真的被视为 00000001,在其他语言(例如 VB)中则为 10000001,而在其他语言中则是除零以外的任何值。这只是在翻译程序语言时需要警惕的另一个陷阱。

相关内容