还有什么比二进制运算更简单的呢?只用两根手指即可计数,一旦你知道它是如何工作的,就会明白计算机使用二进制似乎是自然而然的。但是十进制是如此根深蒂固,以至于我们花了很长时间才意识到两个手指就足够了。

我们太太习惯于计数和做简单的算术,以至于我们往往会忘记,如果你不选择正确的进制系统,那么一切都将非常困难。我们还倾向于认为,我们通常使用的以十为基数的进制系统是如此自然,它必须……嗯,自然!当然实际上不是这样的,有很多不同的计数方法。

为了理解二进制系统,我们首先来看一个数字比0和1多的系统,并且该系统使用了混合基数。

双基数进制系统

你可能会认为,使用十进制值系统是如此显而易见,以至于只有傻瓜才会使用其他任何东西——但英国放弃混合基数进制货币系统的时间并不长,

二十进制系统是混合基系统的一个很好的例子。它首先在12进制中算为先令:12便士等于1先令,然后在20进制中算为英镑:20先令等于1英镑。

英制的度量衡系统仍然在美国和英国使用,它甚至更加古怪。例如,重量首先以16为基数(盎司到磅),然后以14为基数(磅到石),然后以8为基数(石到立方英尺),然后以20为基数(立方英尺到吨)!

10进制系统的吸引力就在于简单性吧!

然而,这并不意味着任何旧的数字系统都能像其他系统一样工作。甚至有人认为,如果不是因为复杂得令人难以置信的混合基数、无进位的进制体系,罗马人会成为更好的工程师。

计算的方式会影响计算的简单程度,因此计算很重要。

基数和进位

那么什么是进制系统,它是如何工作的呢?

这样做的想法是,您首先选择基数,然后安排有足够的符号(任何您喜欢的符号),让它数到比基数小1的数字。

例如,如果您选择3作为基数,则需要0、1、2的符号,但是也可以轻松地使用符号A、B和C。这些符号无关紧要,但是在大多数情况下,我们选择的是传统数字,最多可将值设为9,即使这样做可能会与十进制系统混淆。

以3为基数的计数很快导致所有使用有限数量符号的计数系统所共有的问题。

以3为基数的计数系统很快就会产生一个问题,所有使用有限数量符号的计数系统都存在这个问题。当你数到2并且需要数到3时,你会怎么做? 请记住,你只有符号0、1和2。

答案应该是任何数字计数人员都熟悉的——把3作为一个整体,如1个整体3,不带多余的东西,可以记为10。请注意,这不是“十”,而是“以3为基数的10”。

二进制计算java代码(程序员应知系列)(1)

然后继续进行计数:11(即1个整体3和1),12(即1个整体3和2),然后数到了另一个整体3。因此,现在有两个整体,每个整体为3个,您将其记为20,不是“二十”而是“以3为基数的20”。

二进制计算java代码(程序员应知系列)(2)

你可以像这样继续下去,直到达到22,再加上1就可以将其变成三个整体3,你可以记为100,这意味着你有一新的整体,这个整体有三个整体3。

二进制计算java代码(程序员应知系列)(3)

把它想成一个层次结构,在这个层次结构中,你建立了由三个东西组成的整体,每个东西依次是由三个东西组成的整体,以此类推。

我们可以一整天都在思考这个问题——但现在你要么看到了发生了什么,要么就完全糊涂了。如果你感到困惑,那就用你最熟悉的底数来做同样的步骤,比如以10为底数,看看会发生什么。

进位数值系统

进位数值系统是一个非常聪明的发明,因为你可以使用它给任何数字命名,而不需要无限数量的符号。

你可以看到只需要n个以n为基数的符号,而不是n-1个,因为也需要0来标记一个空的整体n。

按照惯例,对于10以内的基数,我们使用数字0到9,对于大于10的基数,我们使用字母。

字母的使用会让数值系统看起来很奇怪,,并且容易使人感到害怕,但原理却是相同的。

例如,要用十六进制计数,即以16为基数,您需要0到15的符号,即比基数小1,它们是0到9、A、B、C、D、E和F。

以16为基数进行计数,开始时与以10为基数进行计数完全相同,即0、1、2、3、4、5、6、7、8和9,但是由于要以16为基数进行计数,因此不会再跳到10。仅当计数到一个整体16时,才会进位到上一个位置。这样就是,使用A代表10,使用B代表11,依此类推,直到达到F代表15。再加上一个,将有一个整体16,就记为10 - 再次说明,不是“十”,而是“基数为16的10”。

其余部分几乎相同,但将“ FF”称为数字 - 确切地说是255 - 看起来很奇怪,因为那是15组整体16加上一个15的总和。

基本算术

您可以在您想选择的任何基数上进行计数。

如果您愿意,您甚至可以使用混合基数。

回想一下前面列出的金钱、重量和度量的例子,以及如何计算一年中的天数?在这种情况下,我们甚至不会坚持将单一基数放在首位,因为一个月有28、30或31天。考虑这些示例,您将很快了解混合进制计数的全部含义。

更让您惊讶的是,甚至可以在混合基数中包含负数,并且它有一些实际应用——但这是另一个稍微深奥的故事!

对于数值进位系统,任何数值进位系统,同样重要的是它使算术算法变得非常简单。

你可能不知道算术有什么困难,以至于它需要像“算法”这样有尊严的东西,但这只是因为你不是罗马人。

正如我之前所建议的,使用罗马数字进行算术是一个大问题。您可以管理加法,但乘法和除法几乎是不可能的 - 尝试弄清楚如何将 IX 乘以 IIIV 作为一种不会首先转换为十进制或任何其他位值系统的算法。

位值算法允许您通过依次处理每对数字并处理“进位”到下一个位置来计算总和。有趣的是,无论您在哪个基数工作,算法都是相同的——只要您在计算时记得保持在原始的基数上。

例如,如果您想以基数3计算 22 加 21,您将加和第一个,即最低位数字,2 1 以获得结果 10。如果您加和它们并得到 3,那么您就忘记了保持在你正在工作的基数!

所以前两位数相加的结果是0进位1。后两位相加,即高位,2 2 给出结果 11,加上进位1将得出 12。 22 21 的最终答案是 120 - 以3为基数。

二进制计算java代码(程序员应知系列)(4)

加和进位

一般的想法是,您将每个位置的符号相加,然后将任何过大的结果带入下一个位置相加。

这意味着您只需要知道如何添加数字系统的基本符号,然后您就可以添加任何数字对。

为什么是二进制?

同一种加法算法适用于任何数基,为什么要为计算机选择二进制呢?

答案是,至少在最初,二进制的选择根本不明显。

当巴贝奇计划他的巨型机械计算机时,显而易见的选择是十进制。

为什么?

仅仅因为他可以制造以十为一组的齿轮和齿轮,这是他习惯的算术系统。

更重要的是,构建十进制计算机允许输入值,而无需转换为基数 2 的复杂性。 毕竟,这是所有机械计算器使用的方案,所有机械计算器在巴贝奇的想法之前和之后都使用过。

你可以建造一台二进制机械计算机,它会更简单,甚至可能在巴贝奇时代的能力范围内,但这并不是一件显而易见的事情。

在电子计算机的早期,这甚至不是一件显而易见的事情——但它可能应该是。

请记住关于只需要知道如何将基数中使用的符号相加即可将任意两个数字相加的注释。事实证明,这就是为什么二进制是最佳选择的线索。位值相加算法需要一个表,说明每对符号如何相加。

例如在十进制,你需要这样的一个加法表: 0 1 2 3 4 5 6 7 8 90 0 1 2 3 4 5 6 7 8 91 1 2 3 4 5 6 7 8 9 0/12 2 3 4 5 6 7 8 9 0/1 1/13 3 4 5 6 7 8 9 0/1 1/1 2/14 4 5 6 7 8 9 0/1 1/1 2/1 3/15 5 6 7 8 9 0/1 1/1 2/3 3/1 4/16 6 7 8 9 0/1 1/1 2/1 3/1 4/1 5/17 7 8 9 0/1 1/1 2/1 3/1 4/1 5/1 6/18 8 9 0/1 1/1 2/1 3/1 4/1 5/1 6/1 7/19 9 0/1 1/1 2/1 3/1 4/1 5/1 6/1 7/1 8/1

其中符号 8/1 表示结果 8 进位 1。

你可以看到这张表格很大,这是小孩子第一次开始算术时必须学习的东西。 表格的大小让您了解进行位值算术的任何电路或机制的复杂程度。 表中有明显的对称性,可以用来使加法机制更简单,但它仍然是一个相当复杂的表。

现在将其与二进制加法表进行比较:

0 10 0 11 1 0/1

这很简单。 事实上,它就是最简单的加法表,这使得二进制加法机制比任何其他基数更容易实现。

逻辑和开关

在 George Boole 描述了他的布尔逻辑之后,在各种人基于它构建了逻辑机器之后,“真/假”代数的简单性开始被理解。

Charles Pierce 勾勒出如何使用电池和开关来计算逻辑,但这是超前的。五十年后的 1940 年,克劳德·香农再次审视这些想法,注意到他不仅可以构建使用高低电压来表示真假的逻辑电路,还可以构建算术电路。

您所要做的就是写下单个“数字”或位的二进制算术加法表:

A B = R

0 0 0

0 1 1

1 0 1

1 1 0

您可能会认为这是异或的真值表,这确实是将两个位加在一起所需的全部 - 只要您准备忽略进位。

换句话说,二进制符号的加法表与逻辑上的异或相同。

如果要生成进位,则需要向逻辑表中添加另一列

A B = R C

0 0 0 0

0 1 1 0

1 0 1 0

1 1 0 1

现在您可以看到进位只是一个 And 操作。

回顾二进制的加法表,您现在可以看到它只能使用异或和与门来表示。

将两者放在一起,您可以将两位相加并生成一个结果和一个进位——这被称为半加法器,因为它不处理任何关于可能由前一对位加和生成的任何内容。

二进制计算java代码(程序员应知系列)(5)

半加器需要两位并将它们相加以给出结果和进位

要创建一个全加器,我们需要做的就是组合两个半加器,这样第一个加法器将两个位相加以产生结果和进位,第二个将结果和进位相加以产生最终结果和最终进位。

二进制计算java代码(程序员应知系列)(6)

全加器取前一个加法的两位和进位,并产生一个结果和一个进位

在香农发现二进制算术很容易实现后不久,乔治·斯蒂比茨重新发现了同样的想法。 当他突然意识到他可以将开/关位置用作 0/1 并进行算术运算时,他正在思考在电话电路中使用继电器的问题。

他很快就算出了一个半加法器,并用灯泡把它建在厨房的桌子上,以显示结果。 1940 年,他展示了一台简单的二进制中继计算机,在观众席上的是约翰·莫奇利,他继续与约翰·埃克特一起建造了第一台电子计算机——ENIAC。

二进制计算java代码(程序员应知系列)(7)

香农和他的第一个加法器

十进制还没死!

令人震惊的是,ENIAC 是最早的电子计算机之一,它是十进制计算机而不是二进制计算机。

部分原因是在它之前出现的机电计算机是十进制的,但也必须是二进制的优势并不那么明显——尽管这看起来令人难以置信。

早期计算机是十进制的唯一例外是康拉德·祖泽 (Conrad Zuse) 于 1936 年制造的 Z1。他似乎也意识到二进制是在 1935 年构建计算机的方式,这让他强烈声称之前已经想到了这个想法香农或斯蒂比茨。切换到二进制是如此简单,以至于 Zuse 能够在他的厨房桌子上构建完整的计算机。

用二进制表示数字不仅可以连接机电开关电路,还可以连接更先进的电子设备。一旦你决定使用二进制,就很容易找到具有两种状态的物理系统,可以用来表示 0 和 1。这使得创建存储和内存设备变得非常简单。

您可以使用从纸带或卡片上打孔到磁化方向的所有内容来表示二进制数字。但是,有成本效益。如果您使用二进制编码一个数字,那么每个存储位置都存储一个位,但是如果您能找到一种方法在特定位置存储两个以上的状态,那么您可以在同一空间中存储更多数据。

换句话说,二进制数的位数比等效的十进制数的位数多。例如,十进制数 1234 是二进制的 10011010010。二进制数字占用更多空间,我们为了简单而交换空间。例如,某些形式的闪存使用三个或更多电压电平来存储使用非二进制基数的数据。

到目前为止,还没有人回到基础去建造一台十进制计算机,但有一天,当二进制计算机失去动力时,也许巴贝奇会被证明是正确的。

有关二进制数和二进制补码表示的更多信息,请参阅二进制 - 负数

,