[翻译] hpmuseum - RPN

翻译自hpmuseum.org

HP计算器以其惊人的可靠性、高效与高自由度受到世界各地科学工作者与金融界从业人士的热爱,但许多人在RPN这道坎面前望而却步。
为何HP要使用RPN?为何说它是”人类已知最高效的计算器计算公式输入方式“,如何理解与使用RPN呢?

什么是RPN

1920年代时,Jan Lukasiewicz 开发了一种规范的逻辑系统,通过把所有的操作符放在开头(前缀表示法)或最后(后缀表示法),可以不需要括号就能书写数学表达式
举个例子,用常用的中缀表示法写一个式子:
(4 + 5) × 6
在前缀表示法里,是这样写的
× 6 + 4 5 or × + 4 5 6
在后缀表示法中,是这样写的
4 5 + 6 × or 6 4 5 + ×
前缀表示法也被称作“波兰表示法”,以此纪念Lukasiewicz。
HP对后缀表示法进行了一些修改,使之适用于计算器的键盘——HP添加了一个栈来暂存当前操作,提供了移动堆栈的指令。HP将其称作“逆波兰表示法”,也是为了纪念Lukasiewicz

为什么HP要选用RPN?

这种方法被发明后几年,计算机科学家发现对电脑计算来说RPN是一种极其高效的输入方式。
后缀表示法的式子被从前往后读取,运算数被放置在了一个“后入前出”的栈中,运算符能直接对后面几个栈里的数生效
相比之下,拥有括号和优先级差异的中缀表示法需要把运算符推延处理。几乎所有的现在计算机系统编译器处理这类表达式的时候都需要先将式子转换为RPN才能执行(其实,很多计算机厂商设计时都是围绕着RPN开始的(注:汇编语言中有大量RPN风格的操作))
HP35发布时,其他的计算器使用的都是不完整的代数输入系统,他们能处理4+5这样的简单表达式 ;但对复杂的,涉及括号的数学表达式却无能为力。那个时代的科技还没法把完整的表达式翻译器放置在手持计算器上。

而RPN使得HP可以使用那个年代的电脑技术生产能够执行复杂计算的手持计算器,对于大多数用户来说,在拥有执行复杂计算的能力这一点面前,这些学习成本可以忽略不计。而当代数式翻译器真正能被装入手持计算器时,大部分RPN用户则认为RPN无论对人还是对机器都是一种更有效率与统一性的输入方式。并且,由于子表达式在输入时就被执行了,输入时犯错在RPN这里会更加明显,而使用中缀表达式,如果犯了错误比如漏掉一个括号,只有直到整个式子求值完毕才可能被发现。
RPN的另一个优点在于它在不同机器间有极好的统一性,
早期的代数机会告诉你这台机器能处理多复杂的式子,举个例子:Ti Catalogs自70年代晚期开始统计每台机器能处理多少个括号,能执行多少级的运算。即便是今天使用代数计算器,你也需要搞明白这台机器“有多代数”,举个例,有些人因为一元运算符(如RPN中的 5 SIN,有些机器要这样写 SIN(5),更有甚者是 SIN 5 =)而转投RPN,有的计算器甚至没有括号和优先级。大部分代数机无法直接处理这样的式子:
4+5
-------
6+7
即便它们声称自己能“按照书写的方式输入”

学习RPN

如果你买到了基于RPN的计算器,而没能把说明书一起弄到手,你可以看看这一节。这里会介绍大多数RPN机具有的共性
先说几个特别的机型

HP-9100 and HP-9810

这些计算器只有3层栈,这点和后期机型略有区别。而最大的差异在于两个数被操作之后,结果保存在Y栈中,而且Y栈不会自动回落,可以参见hpmuseum.org关于HP-9100系列的页面。

HP-28 and HP-48

这些型号有RPL,这个页面上没有详细介绍
这些型号的操作手册是很好找到的。它们和其他机型最大的区别在于Enter键会将运算数放置于底层栈中,而不是其他机器的X、Y栈,可以参考humuseum.org的相关页面

还记得你一开始是怎么学数学的吗?老师教我们先把要加起来的数字写在一起,然后像这样计算加法:
  25
+12
-------
  37
RPN与这个原理相同,在计算器上输入 25 ,然后按下回车键告诉计算器你完成了一次输入,然后输入 12 ,再按下 + 告诉计算器你要把前面两个数加起来,结果“37”就会被显示出来,加减乘除都是这样操作,把 + 换成其他按键就行了,试试吧~

如果是两个或更多的数,也一样,想要把 5 、 6 , 7 乘在一起,只需输入 5 ENTER 6 × 7 × 然后就出来了结果,注意到输入后两个数并不需要回车键,因为操作键已经告诉了计算器你完成了这次输入。

大多数函数只需要一个操作数,在RPN计算器上,依然只是需要输入数字,并按下操作键即可(大部分所谓的代数计算器其实是用的是同样的方法,键盘上的 SIN 对于计算器而言也不过是类似 × 的东西)举个例子:如果要计算SIN(10),只需输入 10 SIN ,就有结果了;要计算10^5(电脑上表示为e5),输入 5 ex 即可。

只需记住RPN计算器在你按下操作键的那一刻就执行一次运算,因此数字需要被先输入,对于RPN没有所谓“待处理运算”和运算级的概念。如果要输入一长串有顺序的操作数,只需每输入完一个按一次回车即可。

现在你已经掌握了这些机器最基本的使用技巧。RPN的美妙在于他可以不带括号和优先级地处理任何复杂表达式。想要明白这是为什么,需要先了解“堆栈”这个概念

RPN使用几个寄存器作为栈。这里描述的型号有四个寄存器,分别叫“X”Y“Z”和“T”。屏幕上只显示X寄存器。输入数字时,数字被放入X寄存器;当你按下回车键,X中的数字会被移入Y中,后面的数字都被“往上抬”(Z被移入T,Y被移入Z,X被移入Y)来给新的数字腾出地方。下面是一个例子:

Initial Stack After 5 After ENTER
T 4 T 3 T 2
Z 3 Z 2 Z 1
Y 2 Y 1 Y 5
X 1 X 5 X 5
Press: 5 ENTER

当按下 5 ,整个栈被抬升。当回车键被按下时X中的值被复制到Y中,别太在意那两个挤进T中的数(4和3)——四层栈对于大多数复杂运算已经足够了。下面这个例子中的栈将预先被1 2 3 4填满,用来展示栈是怎么工作的。现在把8加到已经输入的5上,看看下面的例子:

Stack from above After 8 After +
T 2 T 2 T 2
Z 1 Z 1 Z 2
Y 5 Y 5 Y 1
X 5 X 8 X 13
Press: 8 +

当按下8时,刚才X中(已经被复制过)的5被替代掉,然后 + 使得X和Y进行了一次运算,结果保存在X中。其余的栈会自动往下掉,来填补加法运算后剩下的那个空位。

你会发现T中的值自动被复制到了Z中,因此T可以被当作一个顺手的常数寄存器使用(下面介绍的Last X也可以这么用)。比方说如果你想计算在4%的利率下,把100刀放在银行,每过一年它会增长多少,可以这样操作,输入: 1.04 ENTER ENTER ENTER ,此时整个栈都被1.04填满,接下来输入 100 按下 × ,获得的是一年以后的总额,再按 × ,则是两年之后。这个操作可以无限进行下去,因为每次按下 × ,栈下落时,T寄存器都会自动被复制一次,使得堆栈中总是有“1.04“这个数字存在。

另一个方便的技巧,用 × 做平方运算:举个例子,计算25的平方,只需输入 25 ENTER × 即可,因为按下回车后,X和Y中都是’25’

在上面的计算中,你非常自如地使用了X和Y寄存器,因为栈会随着你使用的需要自动下落回升。你可以带着同样的轻松去计算一些更加复杂的式子了,比如下面这个:
4+5
-----
6+7
只需按下 4 ENTER 5 + 6 ENTER 7 + ÷ ,下面是原理:

Initial Stack After 4 After ENTER
T 0 T 0 T 0
Z 0 Z 0 Z 0
Y 0 Y 0 Y 4
X 0 X 4 X 4
Press: 4 ENTER 5
After 5 After + After 6
T 0 T 0 T 0
Z 0 Z 0 Z 0
Y 4 Y 0 Y 9
X 5 X 9 X 6
Press: + 6 ENTER
After ENTER After 7 After + After ÷
T 0 T 0 T 0 T 0
Z 9 Z 9 Z 0 Z 0
Y 6 Y 6 Y 9 Y 0
X 6 X 7 X 13 X 0.69
Press: 7 + ÷

你会发现这种执行方式和笔算的过程是非常接近的。

大多数操作会让栈处于自动抬升的状态,而回车(和用于清空X的CLx)会让栈保持原来的状态,当下一个数被置入时,它会替换X寄存器中的内容。这听起来有些奇怪?实际上很好理解并且合乎直觉——回车会复制一次X寄存器到Y中,所以并不需要在键入下一个数字时抬升栈,而CLx时自然也不需要抬升因为X被0替代,别太在意这个,计算器会按照合理的方式运作。

你可以试试更加复杂的表达式,从最里面的括号开始输入,跟用笔解题的步骤类似。看这个例子:
([(4+5)(2+3)+6]/(8+7))^9
输入 4 ENTER 5 + 2 ENTER 3 + × 6 + 8 ENTER 7 + ÷ 9 y^x 然后就可以读出结果60716.99,如果觉得这难以理解,下面有逐步解释:

4 ENTER 5 +
2 ENTER 3 +
×
6 +
8 ENTER 7 +
÷
9 y^x
4+5,内层的一个部分
2+3,另一个内层的部分
现在4+5在Y,2+3在X,把它们乘起来
完成(4+5)(2+3)+6这个部分
计算分母8+7
执行除法运算
计算除法返回结果的9次方

这些步骤和笔算完全相同,计算器会在每步计算后显示一次数值,更容易及时地发现错误。只要稍加练习,RPN一定会成为你的第二运算习惯,并让你再也不想碰代数计算器。

栈操作指令

你可以通过按 R ↓ 来改变栈的顺序,下面是一个“下滚“(Roll Down)的操作示范:

Initial Stack After R dn After 2nd R dn
T 4 T 1 T 2
Z 3 Z 4 Z 1
Y 2 Y 3 Y 4
X 1 X 2 X 3
Press: R dn R dn

按两次 R ↓ 可以使栈回到初始状态。另外还有可以交换X、Y寄存器内容的 x↔y 键,另一些机器也许会有 R ↑ 这样的按键。
CLx 按键是用来清除X中内容的,一些型号也许会有 ← 这样的键,这个键可以逐个删除X中的内容的退格键,某些时候也会表现得像 CLx

Last X

除了上面提到的那些寄存器,大部分HP计算器还带有一个“LAST X”寄存器,自动保留上一次操作前X中的数值,当按下 LAST X 键时,会将之前保留的X值置入现在的X栈中。可以使用这个方法来弥补一些运算上的失误。

1 thought on “[翻译] hpmuseum - RPN”

Leave a Reply

Your email address will not be published. Required fields are marked *