计算机简史 第二章 机械式计算机
在这个时代,人们开始使用工具来辅助计算。
机械式计算机出现的背景
手动时期的计算工具要么是自然界现成的,要么是简单制作而成,原理都十分简单。许多经典的计算工具之所以强大,譬如算盘,是由于依托了强大的使用方法(即算法),工具本身并不复杂,在做计算时,除了动手,还需要动脑,甚至动口(念口诀),必要时还得动笔(记录中间结果),人工成本很高。
而到了 17 世纪,西方开始文艺复兴,解析几何、微积分、概率论等关键理论纷纷发表于世,出现了无理数、虚数、导数、对数等基本概念;当伽利略发明天文望远镜、开普勒提出行星运动三大定律、牛顿发现万有引力创立经典力学;折射与衍射、速度与波动,光的神秘面纱被层层揭开,与此同时,资本主义在扩张,殖民主义在膨胀,航海事业蓬勃兴起,在海上导航就离不开天文历表。科学需要计算,殖民亦然。
为了能更快得到计算的结果,从事特定行业、需要这些常用数值的人们就会购买相应的数学用表(从简单的加法表到对数表和三角函数表等等),以供查询。而这些表中的数值,是由数学家们借助算盘这类简单的计算工具一个个算出来的,算完还要核对。仿佛在做小学的算术作业,脑力活硬生生沦为苦力活。辛苦的结果还往往不见得好,人为计算常常出错,当时出版的数学用表几乎没有一份是零差错的,有时甚至因此而酿成航海事故。
后来,人们用齿轮,旋钮和开关等机械装置,建造了能帮助计算的计算机器。由于是纯机械式的(就好比机械表),我们可以称这些机器为机械式计算机。
举例:这是一款文化牌机械式手摇计算机,天津市红星工厂出品,出厂日期 1972 年 9 月。
截图来自 B 站视频:https://www.bilibili.com/video/BV1X541137xn。
世界上第一个机械式计算机
一名德国的科学家,威廉·契克卡德,曾构思了一种计算机器,其手稿如下:
契克卡德手稿(图片来自《The Rechenuhr (Calculating Clock) of Wilhelm Schickard》,下同)
契克卡德这台传说中的机器后来被称为 Rechenuhr,德语中 Rechnen
表示「算术」,uhr
表示「时钟」,Rechenuhr 便通常译为「计算钟」。跟「钟」有什么关系呢?因为当计算结果溢出(超出 6 位数)时,机器会发出响铃警告,这样的设计在当时可谓相当智能。
契克卡德的手稿被辨认之后,图宾根大学一位名叫布鲁诺·冯·弗雷塔格-洛林霍夫(Bruno von Freytag-Löringhoff)的学者立刻开展了相关研究,并于 1960 年做出了计算钟的复制品:
契克卡德计算钟复制品(原图来自维基「Wilhelm Schickard」词条)
该计算钟支持六位整数计算,主要分为加法器、乘法器和中间结果记录装置三部分,它们虽然集成在同一台机器上,但相互之间没有任何物理关联。位于机器底座的中间结果记录装置是一组简单的置数旋钮,主要是为了省去计算过程中笔和纸的参与,没什么可说的,我们详细了解一下加法器与乘法器的实现原理和使用方法。
如何实现乘法?
乘法器部分其实就是对圆柱形纳皮尔筹的封装,将 0~9
的乘法表印在圆柱面上,圆柱顶端的旋钮分有 10 个刻度,每旋转 36°,就能依次将 0 与 0~9
的乘积、1 与 0~9
的乘积……9 与 0~9
的乘积面向使用者。共有 6 根圆柱,依次旋转 6 个旋钮即可完成对被乘数的置数。横向有 2~9
八根掏有空窗的挡板,代表乘数,左右平移某根挡板便可露出 6 根圆柱在这一行上的数字,即该乘数与被乘数每一位的乘积。
以上面这张纪念邮票上的图案为例,被乘数通过机顶旋钮置为 100722,乘以 4,就移动 4 的那根挡板,露出 100722 各位数与 4 相乘的积:04、00、00、28、08、08,心算将其错位相加得到最终结果 402888。
如何实现加法?通过加法器。加法器部分通过齿轮实现累加功能,计算钟使用单齿进位机构(single tooth carry mechanism),通过在轴上增加一个只有一个齿的齿轮来实现,不妨称之为单齿轮。其进位的原理如下所示:
图来自《01 改变世界》
最内侧的是低位的单齿轮,共有 10 个齿,表示 10 个数字,加 1 则旋转一个齿轮;当顺时针旋转一周,就代表加了 10,左下方的辅助轮就被带动一格,也就是说,进位了 1。
减法与除法
而用这台机器进行除法就有点「死脑筋」了,你需要在被除数上一遍又一遍不断地减去除数,自己记录减了多少次、剩余多少,分别就是商和余数。
计算钟是纳皮尔筹的一种改进,有了加法器,不但弥补了纳皮尔筹不能做加法的缺陷,还为多位数乘法提供了有力助攻。总的来说,计算钟结构比较简单,但依然是人类从手动计算到自动计算的伟大初探,是计算机史上一个重要的里程碑。
帕斯卡计算机
计算钟的进位机构有着一个很大的缺陷——齿轮传动的动力来自人手。同时进行一两个进位还好,若遇上更多位的连续进位——你可以想象,如果是 999999+1,从最低位一直进到最高位,长齿全部与下一位齿轮啮合,齿轮旋转起来相当吃力。齿轮本身却不一定能承受住这么大的力,搞不好容易断裂。
为了解决这一缺陷,帕斯卡尝试了各种改进方法,却发现再精妙的齿轮设计都无法绕开连续进位的魔咒。这个问题不解决,制造机械式计算机就是扯淡。这位天才思前想后,最后破天荒地想到了借助重力——他设计了一种叫 sautoir 的装置,sautoir
来自法语 sauter
,意为「跳」。原理图如下:
低位齿轮在旋转过程中将 sautoir 抬起,每当转过 9 回到 0 时,sautoir 便掉落,其上的爪子推动高位齿轮转动 36°,整个过程 sautoir 就像荡秋千一样从一个齿轮「跳」到另一个齿轮。上一个进位与下一个进位分离,连续进位时产生多米诺骨效应。
往后的一百多年里,许多机械师都对这种前无古人后无来者的绝妙设计赞不绝口。然而,连续进位是没问题了,sautoir 却有着一个致命缺陷——不能反转,这就给使用前的置零制造了麻烦,需要从个位开始依次将每一位数转到 9,而后在个位上加 1 以产生连续进位,完成所有位的置零。
可齿轮不能反转的话,怎么实现减法呢?帕斯卡想出了一种用加法代替减法的方案,正是计算机中沿用至今的补码思想。 例如一个手表,目前时间是 4 点钟,想要调成 3 点钟,即减一小时,如何做呢?两种做法
- 直接减去 1
- 直接加上 11 个小时,时针就会落到 3 点钟
为什么可以这么做呢?因为我们知道,手表上只有 12 个刻度,当超过 12 的时候,就会重新开始:
4-1 = 4 - (12 -11) = 4 + 11 -12,最后 12 会被忽略掉。后续我会在《数字电路》专栏里展开讲这个补码。
巴贝奇:现代计算机真正的鼻祖
随着对计算的规模和准确性要求越来越高,出现了很多更优秀的机械式计算机,例如莱布尼茨步进计算器,托马斯算数仪,按键式计算器,计算机的体积也越来越小,甚至可以放到口袋里,但始终离不开人的操作。
为了解决一个数学问题,人们往往需要将多步运算串联起来,每一次串联不过是将上一步的运算结果直接或经过简单处理后交给下一步而已,而既然运算可以由机器完成,为什么步骤就不可以呢?
巴贝奇发明了一种高度自动化的计算机器——差分机。
什么是差分
在讲解差分机之前,我们先讲讲什么是差分。
帕斯卡在 1654 年提出了差分思想:n 次多项式的 n 次数值差分为同一常数。这句话概括性高,不太好理解,用几个例子来详细说明。
我们这里构造一次函数 F(x): F(x) = 10x + 24
同时定义差分函数 ∆F(x): △F(x) = F(x+1) - F(x)
在 x 取 0~6 时,F(x)及 ∆F(x)的值如下表所示:
x | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
F(x) | 24 | 34 | 44 | 54 | 64 | 74 | 84 |
△F(x) | 10 | 10 | 10 | 10 | 10 | 10 | 10 |
不难发现,对于一次多项式,每个相邻的 x 所对应的 F(x)之差都是一个常数,这个常数正是 x 的系数。那么二次多项式呢?
构造二次函数 F(x):F(x) = 10x2 + 2x + 4
同时定义一次差分与二次差分:
△F1(x) = F(x+1) - F(x)
△F2(x) = △F1(x+1) - △F1(x)
在 x 取 0~6 时,F(x)及其一次、二次差分的值如下表所示:
x | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
F(x) | 4 | 16 | 48 | 100 | 172 | 264 | 376 |
△F1(x) | 12 | 32 | 52 | 72 | 92 | 112 | |
△F2(x) | 20 | 20 | 20 | 20 | 20 |
对于二次多项式,每个相邻的 x 所对应的一次差分之差(即二次差分)是一个常数。
一次多项式和二次多项式的规律如此,三次、四次,乃至任意多次的多项式都遵循这样的差分规律——n 次多项式的 n 次差分为常数。
差分规律是一项伟大的发现,有了差分,在计算多项式时就可以用加法代替乘法,我们只需要准备好 x=0 时 F(x)及各次差分的值,后面任意 x 所对应的 F(x)值均可通过加法得出。
只要有了第 1 列 F(0)、F1(0) 和 F2(0) 的值,第 2 列的 F(1)即可通过 F(0) + F1(0) 得到、F1(1) 可通过 F1(0) + F2(0) 得到;同理,第 3 列的 F(2)和 F1 (2)也可根据第 2 列的数据得到;以此类推,任意列的数据都可通过前一列的数据得到,即求解 F(n),只需前 n 列数据的不断迭代。
而这整个过程,只涉及加法。这可了不得!要知道,许多常见的函数在数学上称为解析函数,它们都可以用多项式逼近(幂级数展开),常用的三角函数、对数函数都可以转换为多项式。借助差分思想,这些函数可以进一步转换为重复的加法。而加法运算正是机械计算器的“拿手好戏”,这样一来,绝大部分数学运算就都可以交给机器了。
差分机的提出背景
差分机的设想,最早由一位名为约翰·赫尔弗里奇·冯·米勒(Johann Helfrich von Müller)的德国工程师在 1784 年提出,但他没有得到资金支持,这一历史重任最终留给了巴贝奇。
巴贝奇与差分机的故事,要从 1789 年法国大革命说起。君主制被推翻后,新成立的国民议会大刀阔斧地推行着多方改革,其中一项很重要的工作就是统一全国混乱不堪的度量衡,这项旷日持久的工程直接导致了后来国际米制的诞生,成为法国对世界科学最伟大的贡献之一。于此同时,原本的数学用表不再适用,需要重新编制。1791 年,这项艰巨的任务落在了数学家加斯帕德·德普罗尼(Gaspard de Prony)肩上。
表的规模十分庞大,计算结果需要精确到小数点后 14~29 位,工作量之巨,已经远不能作为一项数学任务去对待,它已经是个正儿八经的工程。普罗尼想到经济学家亚当·斯密(Adam Smith)那本经典的《国富论》,其中劳动分工的理念令他颇受启发。普罗尼将制表人员分成金字塔式的三层:
- 第一层为 5~6 名顶级的数学家,负责选择公式、确定计算精度和计算范围
- 第二层为 7~8 名普通的数学家,负责计算一些关键数据和初始数据,并为第三层提供计算模板、方法
- 第三层为 60~80 名只会基本算术的计算员,负责完成耗时耗力的重复运算,他们大多是失业的理发师,因为大革命后,上流社会的发型设计市场跟着贵族阶层一起瓦解了
单词 computer 最早出现于 1613 年英国作家理查德·布雷斯韦特(Richard Braithwait)的一本书中,指的不是机器,而是“负责计算的人”,即计算员。直到 1897 年,computer 才有了“计算机器”的意思。在此之前,computer 是一种地位不高的职业,往往由作为廉价劳动力的妇女或失业者从事,他们不需要有多高的文化程度,经过培训,借助机械计算器或手动计算工具帮助科学家和工程师完成一系列最基本的数学运算即可。他们和计算机一样,经过编程,按部就班地执行既定步骤。
“图片来自《三体》 人列计算机”
这种创新式的分工方式不仅帮助普罗尼顺利完成了任务,还使他有了足够的自信宣称“制作数学用表可以像生产针一样简单”。
然而最大的问题是,成表的正确率却不尽人意,尽管普罗尼要求每个数据至少计算两遍,并且要在法国的不同地点用不同的方法完成。其实,那个时代基本没有一版数学用表是完全正确的,有些版本甚至错误百出。这些错误可能会造成很严重的后果,比如航海表一旦在关键地方出错可以直接导致船毁人亡。
差分机概念的提出
巴贝奇意识到:只要是人为的,就没有完美的。他思忖着:普罗尼分工模式的最底层,那个最简单却也是最吃力的层次,人员最多也是产生最多错误的层次,可否用机器来代替呢?
1822 年 6 月 14 日,巴贝奇向皇家天文学会递交了一篇名为《论机械在天文及数学用表计算中的应用》的论文,差分机的概念正式问世。
与论文一起亮相的,是一台简单的原型机——差分机 0 号。英国政府对它很有兴趣,并于次年拨款 1700 英镑,希望巴贝奇能做出实用产品,彻底解决制表难题。
拿到启动资金的巴贝奇如鱼得水,立即着手差分机 1 号的研制,并宣称只需两三年就能完成任务。谁知实行起来要比想象中困难得多,那个时代的机械制造水平实在满足不了差分机的精密要求,巴贝奇跑遍整个欧洲也没找到多少能用的零件,于是在制造机器之前,还要先考虑怎么制造各类零件。在当时一位顶尖的英国机械师约瑟夫·克莱门特(Joseph Clement)的帮助下,巴贝奇不但做出了差分机能用的零件,还培养出大批优秀的技师。
也正因如此,他们无意间将一个项目的摊子铺到了一个行业的尺度,尽管实施的过程精雕细琢、尽善尽美,却没能交付一件满足要求的产品。1832 年,项目启动 10 年过去了,巴贝奇却只完成了设计稿的七分之一——一台支持 6 位数、2 次差分的小模型(设计稿为 20 位数、6 次差分)
(图片来自《Babbage Difference Engine in Motion》)
分析机
差分机的建造虽然夭折了,但巴贝奇从未停止过对设计稿的改进。直到有一天,一个惊人的想法从他脑中掠过,如同神祇,如同有史以来所有人类对计算的诉求结晶——差分机固然强大,但终究只能计算多项式而已,何不建造一台可以解决所有计算问题的通用机器呢?
1833 年,巴贝奇就着手开始了这种通用机器的设计,并不断改进直至离世。这台被他称作分析机(Analytical Engine)的机器,直接将机械计算的理念从地表推上云天。
巴贝奇将分析机划分为 5 大部分:
- 由差分机的计数装置改进而来的数据存储器,可存储 1000 个 40 位十进制数;
- 支持四则运算、比较大小和开平方根的算术单元,巴贝奇称之为“工厂”(mill);
- 实现逻辑控制的圆柱形“控制筒”,身周固定着许多销钉,随着“控制筒”的旋转,通过销钉推动杠杆实现控制;
- 3 种用于输入的读卡装置,其一输入运算指令,其二输入常量数据,其三输入控制数据(在存储器和算术单元之间)传输的指令,承载这些输入信息的是一种名为穿孔卡片(punched card/punch card)的经典载体,3 种读卡装置分别识别 3 种类型(运算、数据和控制)的穿孔卡片;
- 4 种输出装置,其一为打印装置,其二为曲线绘图仪,其三为响铃,其四为打孔机,用于制造穿孔卡片。
分析机使用的穿孔卡片——上:数据类卡片|下:运算类卡片(图片来自维基百科)
后人惊讶地发现,这种组成结构竟和现代计算机如出一辙(现代计算机的五大组成部件是由冯·诺依曼在 1945 年才明确提出的)。
五大部件的协作过程大体是这样的:
- 读卡装置从穿孔卡片上读取数据和运算指令
- 数据进入存储器,随后被传送至“工厂”进行处理
- 处理结果进入存储器并通过输出装置呈现给用户。
在控制类穿孔卡片的指引下,“控制筒”可以实现顺序、循环、条件等多种控制逻辑,读取数据的读卡装置则不但可以按照正常顺序读卡,还可以反序读卡,乃至跳过部分卡片。
巴贝奇首次将运行步骤从机器身上剥离,靠随时可以替换的穿孔卡片来指挥机器,成就了机器的可编程性。这其中,穿孔卡片的引入功不可没。这种经典的数据载体跨越了机械、机电和电子 3 个时代,一直沿用至 20 世纪 80 年代中期。
纵观整个机械时期,巴贝奇的思想远远超出了其他几位先驱者,他如同一个从 20 世纪穿越回去的先知,把一百年后的思想“剧透”给了世人。唯一缺憾的,是不论差分机还是分析机,巴贝奇都终究没能实现。人类的技术发展错过了一次“跳级”的机会,巴贝奇在计算机领域的成就逐渐没入历史的浓雾,等待百年之后再被另一批天才重新发明。