Reverse Polish notation
Reverse Polish notation (RPN), also known as postfix notation, is a mathematical notation system in which every operator follows its operands, allowing expressions to be written unambiguously without parentheses or operator precedence rules. For instance, the infix expression $3 + 4 \times 5 becomes 3 4 5 × + in RPN, evaluated from left to right using a stack where operands are pushed and operators pop the required number of values, apply the operation, and push the result back.[1]
RPN originated as the reverse of Polish notation, a prefix system developed by Polish logician Jan Łukasiewicz around 1924 to represent logical statements without parentheses, facilitating mechanical analysis and truth-table computation.[2] The postfix variant was first proposed in 1954 by Arthur W. Burks, Don W. Warren, and Jesse B. Wright for designing a relay-based logical machine that processes parenthesis-free formulas using a stack-like evaluator to compute truth values efficiently. It was independently reinvented in 1960 by Friedrich L. Bauer and Klaus Samelson, who described its use in sequential formula translation for early compilers, leveraging a pushdown store (stack) to handle expression evaluation during program assembly.[3]
In computing, RPN enables straightforward parsing and evaluation of expressions, forming the basis for algorithms like the shunting-yard algorithm used in many compilers to convert infix to postfix form.[3] It powers stack-based virtual machines, such as the Java Virtual Machine's bytecode execution model, where instructions mimic RPN operations for arithmetic and control flow. Notably, Hewlett-Packard adopted RPN in its pioneering calculators starting with the 9100A desktop model in 1968 and the handheld HP-35 in 1972, allowing efficient entry of complex calculations with fewer keystrokes and no parentheses.[4][5] RPN also underpins languages like Forth, where code is structured as postfix sequences for real-time embedded systems. Its advantages include reduced computational overhead in expression trees and unambiguous serialization, making it valuable in symbolic computation, circuit design, and query optimization in databases.[1]
Fundamentals
Definition and Syntax
Reverse Polish notation (RPN), also known as postfix notation, is a mathematical notation system in which operators are placed after their corresponding operands, thereby eliminating the need for parentheses to denote operator precedence in unambiguous expressions.[6][1] This approach contrasts with traditional infix notation, where operators appear between operands (e.g., as in standard arithmetic writing), and prefix notation (also called Polish notation), where operators precede their operands.[6][7]
The syntax of RPN consists of a linear sequence of tokens processed from left to right, where each token is either an operand—such as a number or variable—or an operator.[1][8] Operands are introduced first in the sequence, immediately followed by the unary or binary operator that applies to them, ensuring that the structure inherently defines the order of operations without additional delimiters.[6][9] Binary operators require exactly two preceding operands, while unary operators act on one, maintaining a postfix arrangement that supports stack-based evaluation, though the mechanics of evaluation are separate from the notation's definition.[1][7]
Formally, an RPN expression is represented as a one-dimensional array or string of tokens, where the entire expression resolves to a single value through sequential application of operators to available operands.[6][8] This token-based format allows for unambiguous parsing in computational contexts, distinguishing RPN from infix by its operand-operator ordering and from prefix by its reversed positioning of operators relative to operands.[1][9]
Basic Examples
To illustrate the syntax of Reverse Polish Notation (RPN), consider simple arithmetic expressions where operands precede operators, and evaluation proceeds from left to right using a stack data structure. In RPN, numbers are pushed onto the stack, and operators pop the required operands, perform the operation, and push the result back. This avoids the need for parentheses in basic cases.[10]
A fundamental example is the addition of two numbers: the expression 3 4 + evaluates to 7. The stack simulation proceeds as follows:
- Push 3: stack = [11]
- Push 4: stack = [3, 4]
- Apply +: pop 4 and 3, compute 3 + 4 = 7, push 7: stack = [12]
The final stack value is 7.[10]
For multiplication followed by addition, such as 2 3 * 5 +, which equals 11, the steps are:
- Push 2: stack = [13]
- Push 3: stack = [2, 3]
- Apply *: pop 3 and 2, compute 2 × 3 = 6, push 6: stack = [14]
- Push 5: stack = [6, 5]
- Apply +: pop 5 and 6, compute 6 + 5 = 11, push 11: stack = [15]
This demonstrates how RPN handles operator precedence implicitly through stack order.[15]
Subtraction requires attention to operand order, as the top of the stack (right operand, first popped) is subtracted from the preceding operand (second popped): 5 3 - yields 2 (5 - 3). Stack steps:
- Push 5: stack = [17]
- Push 3: stack = [5, 3]
- Apply -: pop top (3), pop next (5), compute 5 - 3 = 2, push 2: stack = [13][18]
Similarly, for division, 10 4 / results in 2.5:
- Push 10: stack = [19]
- Push 4: stack = [10, 4]
- Apply /: pop top (4), pop next (10), compute 10 ÷ 4 = 2.5, push 2.5: stack = [2.5][18]
Exponentiation, denoted by ^, follows binary convention with the base as the first operand: 2 3 ^ equals 8.
- Push 2: stack = [13]
- Push 3: stack = [2, 3]
- Apply ^: pop top (3), pop next (2), compute 2³ = 8, push 8: stack = [20][15]
RPN also accommodates unary operators, which pop a single operand. For the square root of 5, denoted 5 √, the result is approximately 2.236:
- Push 5: stack = [17]
- Apply √: pop 5, compute √5 ≈ 2.236, push 2.236: stack = [2.236][21]
Historical Development
Origins in Polish Notation
Polish notation, also known as prefix notation, was developed by the Polish philosopher and logician Jan Łukasiewicz in the early 1920s as a method to represent logical and mathematical expressions without the need for parentheses, thereby eliminating ambiguity in operator precedence.[22] Łukasiewicz first introduced this notation in 1924, drawing inspiration from the way mathematicians denote functions by placing the function symbol before its arguments, such as f(x).[22] In this system, operators precede their operands, allowing expressions to be written linearly and unambiguously, for instance, representing the implication p \rightarrow q as \text{C}pq, where C stands for the connective of implication.[22]
The primary motivation behind Polish notation was to simplify the notation of propositional logic, where traditional infix expressions often required extensive parentheses to resolve ambiguities, such as in chained implications like p \rightarrow q \rightarrow r.[22] By prefixing operators, Łukasiewicz aimed to enhance clarity and brevity, reducing the symbol count significantly—for example, a complex formula might use 23 symbols in Polish notation compared to 43 in fully parenthesized infix form.[22] Early applications focused on philosophy and mathematics, particularly in Łukasiewicz's work on the propositional calculus and the semantics of implication, where the notation facilitated precise analysis of logical structures without visual clutter.[22] This approach was particularly useful in his studies of many-valued logics and the history of Aristotelian syllogistics, influencing subsequent developments in formal logic.
The postfix variant of this notation, known as reverse Polish notation (RPN), was first proposed in 1954 by Arthur W. Burks, Don W. Warren, and Jesse B. Wright in their analysis of a relay-based logical machine that used stack-like evaluation for parenthesis-free formulas.[23] It was independently described in 1960 by Friedrich L. Bauer and Klaus Samelson for sequential formula translation in early compilers, utilizing a pushdown store.[3] Further contributions came in the mid-1950s from Australian philosopher and computer scientist Charles L. Hamblin, who extended the scheme by proposing the reversal for addressless coding compatible with stack-based architectures, where operands are pushed onto a stack before the operator pops and processes them, enabling efficient, parenthesis-free computation without recursive parsing.[24] In his 1957 presentation at the W.R.E. Conference on Computing, titled "An Addressless Coding Scheme based on Mathematical Notation," Hamblin outlined this postfix variant as an adaptation of Łukasiewicz's prefix system, demonstrating its utility in programming languages like GEORGE, which he developed that same year for the DEUCE computer.[24] This reversal preserved the ambiguity-free nature of Polish notation while aligning it with the sequential processing capabilities of stack-oriented machines, laying the theoretical groundwork for its later computational adoption.[24]
Adoption in Computing and Calculators
Reverse Polish notation (RPN) found early adoption in computing through stack-based architectures that facilitated efficient expression evaluation without parentheses. In the late 1960s, Charles H. Moore developed the Forth programming language, which inherently employed RPN to leverage a data stack for operations, enabling compact code suitable for resource-constrained environments like early minicomputers and embedded systems.[25] This approach influenced subsequent stack-oriented languages and hardware designs, such as those in real-time control applications during the 1970s.[26]
The integration of RPN into calculators marked a significant milestone in mid-20th-century hardware. The Friden EC-130, introduced in 1963, was the first fully electronic desktop calculator to implement RPN, using a cathode-ray tube display and a multi-register stack to process postfix expressions efficiently.[27] This innovation preceded broader commercialization, demonstrating RPN's practicality for scientific computations in an era of emerging solid-state technology.
Hewlett-Packard's contributions accelerated RPN's spread in the late 1960s. The HP-9100A, released in 1968, became the first programmable scientific desktop calculator employing RPN, allowing users to store and execute complex routines via magnetic cards while supporting floating-point arithmetic.[4] Developed at HP's Loveland facility, it bridged calculators and computers, influencing the design of subsequent handheld models like the HP-35 in 1972.
Regional developments further expanded RPN's use. In the Soviet Union, the Elektronika B3-19M, launched in 1977, represented the first domestically produced RPN calculator, followed by the programmable B3-21 that same year, both aimed at educational and engineering applications in state institutions.[28] By the mid-1970s, RPN had transitioned from niche scientific tools to programmable devices across manufacturers, solidifying its role in professional computing workflows due to streamlined evaluation processes.[29]
Conversion Techniques
Infix to RPN Algorithm
The Shunting-yard algorithm, developed by Edsger W. Dijkstra in 1961, provides a systematic method to convert infix mathematical expressions into reverse Polish notation (RPN) by parsing tokens from left to right while respecting operator precedence and associativity.[30] It employs an operator stack to temporarily hold operators and an output queue to build the RPN sequence, simulating the shunting operations in a railway yard where incoming operators are either added to the stack or rerouted to the output based on priority rules.[30]
Operators are assigned numerical precedence levels, with higher values indicating tighter binding; for instance, multiplication (*) and division (/) typically have precedence 10, while addition (+) and subtraction (-) have precedence 9.[30] Operators of equal precedence are handled as left-associative, meaning they are popped from the stack to the output before pushing the new operator, ensuring evaluation from left to right (e.g., in "A + B + C", the first + is resolved before the second).[31] Parentheses override precedence by isolating subexpressions on the stack.
The algorithm processes a tokenized infix expression as follows (pseudocode adapted for clarity):[31]
Initialize an empty output queue and an empty operator stack.
While there are tokens to read in the input:
Read the next token.
If the token is an operand (e.g., variable or number), add it to the output queue.
If the token is an operator o1:
While the operator stack is not empty and the top operator o2 has precedence greater than or equal to o1 (and o1 is left-associative for equal precedence):
Pop o2 from the operator stack and add it to the output queue.
Push o1 onto the operator stack.
If the token is a left parenthesis '(', push it onto the operator stack.
If the token is a right parenthesis ')':
While the top of the operator stack is not a left parenthesis:
Pop the operator from the stack and add it to the output queue.
Pop the left parenthesis from the operator stack (do not add to output).
After processing all tokens, while the operator stack is not empty:
Pop operators from the stack and add them to the output queue.
Initialize an empty output queue and an empty operator stack.
While there are tokens to read in the input:
Read the next token.
If the token is an operand (e.g., variable or number), add it to the output queue.
If the token is an operator o1:
While the operator stack is not empty and the top operator o2 has precedence greater than or equal to o1 (and o1 is left-associative for equal precedence):
Pop o2 from the operator stack and add it to the output queue.
Push o1 onto the operator stack.
If the token is a left parenthesis '(', push it onto the operator stack.
If the token is a right parenthesis ')':
While the top of the operator stack is not a left parenthesis:
Pop the operator from the stack and add it to the output queue.
Pop the left parenthesis from the operator stack (do not add to output).
After processing all tokens, while the operator stack is not empty:
Pop operators from the stack and add them to the output queue.
This produces the RPN in the output queue, ready for evaluation.[31]
Extensions to the basic algorithm accommodate functions and unary operators by treating them as special high-precedence operators. Functions like sin are tokenized as unary operators; when a function name is encountered, it is pushed onto the stack, and upon reaching the closing parenthesis of its argument, the function is popped to the output after the argument subexpression (e.g., the infix "sin(x)" converts to the RPN "x sin").[8] Unary operators, such as negation (-x), are distinguished from binary ones during tokenization (e.g., unary if following an operator or start of expression) and assigned higher precedence than binary operators, allowing them to bind tightly without popping intervening binary operators.[8]
To illustrate, consider converting the infix expression "(A + B) * C" to RPN using the algorithm:[31]
- Token '(': Push to stack. Stack: ['(']
- Token 'A': Output: [A]
- Token '+': Push to stack (stack top is '('). Stack: ['(', '+']
- Token 'B': Output: [A, B]
- Token ')': Pop until '(': Pop '+' to output, then pop '('. Output: [A, B, +]
- Token '': Stack empty, so push ''. Stack: ['*']
- Token 'C': Output: [A, B, +, C]
- End of input: Pop '*' to output. Output: [A, B, +, C, *]
The resulting RPN is "A B + C *", which correctly groups the addition before multiplication due to precedence handling.[31]
Evaluation of RPN Expressions
The evaluation of Reverse Polish Notation (RPN) expressions relies on a stack-based algorithm that scans the expression from left to right, processing tokens sequentially to compute the result without requiring parentheses or operator precedence rules.[32] This method leverages the postfix structure of RPN, where operands appear before their operators, allowing straightforward operand accumulation and operation application.[33]
The algorithm initializes an empty stack to hold operands and intermediate results. For each token in the RPN expression:
- If the token is an operand (typically a number), push it onto the stack.
- If the token is a binary operator (such as +, -, *, or /), pop the top two elements from the stack (let the second pop be the right operand and the first pop the left operand), apply the operation (e.g., left + right), and push the result back onto the stack.
- If the token is a unary operator (such as negation, denoted as ~ or - in some contexts), pop the top element, apply the operation, and push the result back.[32][33][34]
Upon completing the scan, the stack should contain a single element representing the expression's value, which is then popped as the final result. If the stack is empty or contains multiple elements at the end, the expression is invalid.[32]
Error conditions during evaluation include stack underflow, which occurs when an operator is encountered but fewer than the required number of operands (one for unary, two for binary) are available on the stack.[33] Type mismatches, such as applying an arithmetic operator to non-numeric tokens, can also arise, though valid RPN expressions typically consist solely of numbers and operators.[32]
The following pseudocode illustrates the evaluator, assuming numeric operands and basic arithmetic operators for simplicity:
function evaluateRPN(tokens):
stack = empty stack
for each token in tokens:
if token is operand:
push stack, convert(token to number)
else if token is binary operator:
if stack size < 2:
raise underflow error
right = pop stack
left = pop stack
result = apply(left, token, right)
push stack, result
else if token is unary operator:
if stack size < 1:
raise underflow error
operand = pop stack
result = apply(token, operand)
push stack, result
if stack size != 1:
raise invalid expression error
return pop stack
function evaluateRPN(tokens):
stack = empty stack
for each token in tokens:
if token is operand:
push stack, convert(token to number)
else if token is binary operator:
if stack size < 2:
raise underflow error
right = pop stack
left = pop stack
result = apply(left, token, right)
push stack, result
else if token is unary operator:
if stack size < 1:
raise underflow error
operand = pop stack
result = apply(token, operand)
push stack, result
if stack size != 1:
raise invalid expression error
return pop stack
[32][33]
Consider the RPN expression "3 4 2 + -", equivalent to the infix 3 - (4 + 2):
- Push 3: stack = [11]
- Push 4: stack = [3, 4]
- Push 2: stack = [3, 4, 2]
- Encounter +: pop 2 (right) and 4 (left), compute 4 + 2 = 6, push 6: stack = [3, 6]
- Encounter -: pop 6 (right) and 3 (left), compute 3 - 6 = -3, push -3: stack = [-3]
- End of expression: pop -3 as result.[33]
Advantages and Applications
Computational Benefits
Reverse Polish notation (RPN) eliminates the need for parentheses in mathematical expressions by placing operators after their operands, which significantly reduces parsing complexity in compilers and interpreters. This postfix structure ensures unambiguous expression representation, as each operator unambiguously applies to a fixed number of preceding operands without requiring precedence rules or grouping symbols during evaluation. Consequently, RPN avoids the operator precedence issues inherent in infix notation, allowing for straightforward, error-free processing by machines.[35]
The evaluation of RPN expressions relies on a stack data structure, where operands are pushed onto the stack and operators trigger pop operations to compute results in constant time, O(1), per operation.[35] Overall, this stack-based approach achieves linear time complexity, O(n), for evaluating an expression of length n, as it requires only a single left-to-right pass without backtracking.[35] Such efficiency makes RPN particularly suitable for devices with limited memory, where stack operations minimize overhead and temporary storage needs.[36]
In terms of resource utilization, RPN expressions are typically shorter than their infix equivalents due to the absence of parentheses and explicit precedence indicators, leading to space savings in storage and transmission. The space complexity remains O(n) via the stack, but the overall processing is faster for machines, as subexpressions are evaluated immediately upon encountering operators, optimizing computational throughput compared to multi-pass infix parsing.[35]
While RPN offers substantial benefits for automated computation, it presents a steeper learning curve for human users accustomed to infix notation, potentially increasing initial cognitive load despite its machine-oriented simplicity.
Use Cases in Modern Systems
In modern virtual machines, Reverse Polish Notation (RPN) plays a key role through postfix-style bytecode in systems like the Java Virtual Machine (JVM). The JVM employs a stack-based operand stack for executing instructions, where operations such as addition or multiplication pop arguments from the stack and push results, mirroring postfix evaluation without requiring operator precedence handling. This structure, defined in the JVM specification, enables efficient interpretation and just-in-time compilation of Java programs by processing expressions linearly.[37]
Spreadsheet software, including Microsoft Excel, internally represents formulas in RPN to facilitate storage and computation. User-entered infix expressions, such as =SUM(A1:A10), are tokenized and converted to a postfix sequence in binary file formats like XLSB, allowing stack-based evaluation that propagates results across dependent cells with minimal parsing overhead. This approach, part of Excel's parsed expression system, supports complex, interdependent calculations in large worksheets.[38]
In AI and symbolic computation, RPN aids in linearizing expression trees for evaluation in environments like Wolfram Mathematica. Mathematica supports converting symbolic expressions to RPN for streamlined processing in algebraic manipulations, where the postfix form simplifies traversal and computation of nested operations.[39]
Embedded systems leverage RPN for efficient sensor data processing on resource-limited microcontrollers, often via Forth implementations on Arduino platforms. Forth's stack-based RPN syntax enables real-time scripting in libraries like AmForth, where developers define words for fusing inputs from sensors like accelerometers or temperature probes, optimizing memory and execution speed in interrupt-driven applications. This notation's postfix simplicity reduces code size and avoids recursion overhead, making it ideal for battery-powered IoT devices.[40]
In recent blockchain developments, RPN underpins smart contract scripting in platforms like Bitcoin, where the Script language uses postfix notation for transaction conditions and validations. Bitcoin Script processes operations on a stack, such as OP_ADD for combining values, enabling secure, non-Turing-complete execution of rules like multisignature approvals without loops.[41]
Implementations
Hardware Devices
The Hewlett-Packard HP-35, introduced in 1972, was the world's first pocket-sized scientific calculator to utilize Reverse Polish Notation (RPN), featuring transcendental functions and a four-level stack for efficient computation without parentheses.[5] This handheld device, powered by early integrated circuits and displaying results on red LED digits, marked a pivotal shift from bulky desktop models to portable tools for engineers and scientists.[42] Subsequent HP series built on this foundation, including the programmable HP-41C released in 1979, which offered expandability via synthetic programming and ROM modules while maintaining RPN entry for complex operations.[43]
Other manufacturers adopted RPN in the 1970s to compete with HP's innovation, often licensing technology or reverse-engineering designs for cost efficiency. The Sinclair Scientific, launched in 1974 by the British firm Sinclair Radionics, was a compact, low-cost device using RPN with a limited scientific function set implemented via a reprogrammed four-function chip, displaying results in scientific notation on a single-line LED.[44] Commodore International's MM6X model (X variant), introduced in 1974, incorporated RPN for basic scientific calculations, featuring a slide-rule-like design with LED output and battery power.[45] In the Soviet Union, the Elektronika MK-52, produced from 1983 to 1992 by factories including Semico, was a programmable RPN calculator with 105 program steps, 15 registers, and vacuum fluorescent display, reflecting adaptations of Western RPN concepts for domestic engineering needs.[46]
Niche devices from the 1970s further diversified RPN hardware, appealing to hobbyists and specialized users. Prinztronic, a British brand under Dixons, released the Programmable Scientific Calculator in 1975, an RPN model with 102 program steps and a three-level stack, manufactured in Taiwan for affordable scientific use.[47] Heathkit's OC-1401 Aircraft Navigation Computer, available as a 1978 kit or assembled unit, employed a five-level RPN stack tailored for aviation calculations, including great-circle navigation functions on an LED display.[45] Soviet adaptations extended to earlier models like the Elektronika B3-19 (1975), which used RPN for basic scientific tasks in a rugged, domestically produced form factor.[45]
In the 2000s and 2010s, RPN persisted in professional-grade hardware, evolving from LED displays to advanced graphing capabilities. The HP 50g, introduced in 2006, supported RPN alongside algebraic modes in a graphing calculator with symbolic computation, infrared connectivity, and a high-resolution monochrome screen, serving as a staple for engineers until its discontinuation around 2015.[48] Community-driven projects revived RPN in modern contexts, such as FPGA-based implementations in the 2010s that emulated classic HP logic on reconfigurable hardware for customizable, open-source devices.[49] SwissMicros has produced modern RPN hardware since 2017, including the DM42, a programmable scientific calculator emulating the HP-42S with 34-digit precision, alphanumeric display, and USB connectivity, followed by the DM42n variant. As of November 2025, SwissMicros released the R47, a high-end RPN model with refined software for complex operations, matrix handling, and numerical integration.[50][51] As of 2025, HP continues RPN in select models like the HP 12C financial calculator and the HP Prime graphing calculator, which includes configurable RPN mode for stack-based entry, underscoring its enduring role in professional tools from early LED portables to contemporary graphing systems.[52] This progression highlights RPN's adaptability, from power-hungry 1970s LEDs requiring frequent battery changes to efficient LCDs and CAS-integrated graphers that maintain stack efficiency for complex workflows.[42]
Software and Programming Languages
Reverse Polish notation (RPN) has been natively incorporated into several programming languages, particularly those that are stack-oriented, where operands are pushed onto a stack and operators pop and apply operations in postfix order. Forth, developed by Charles H. Moore starting in the late 1960s and reaching maturity around 1970, is a quintessential example of an RPN-native language designed for embedded systems and real-time applications, emphasizing simplicity and extensibility through its stack-based execution model.[25] PostScript, introduced by Adobe Systems in 1984 as a page description language for desktop publishing, employs RPN for its operand-operator syntax, enabling concise representation of complex graphics and text layout instructions in printer drivers and rendering engines.[53]
Stack-oriented languages from the late 1990s and 2000s further exemplify RPN semantics in purely functional paradigms. Joy, created by Manfred von Thun in 2001, is a concatenative programming language that relies on function composition and stack manipulation without variables, using RPN-style notation to build programs from quotations and combinators for tasks like symbolic computation.[54] These languages promote a postfix evaluation model that avoids recursion through iteration and stack operations, influencing modern esoteric and experimental programming designs.
Software implementations of RPN appear prominently in calculator emulators and open-source tools. The HP Prime graphing calculator, released in 2013, includes an RPN mode alongside algebraic entry, with official PC and mobile emulators available for simulating its stack-based computations on desktops and Android devices.[55] Open-source alternatives, such as Free42—a programmable simulator of the HP-42S RPN calculator—provide high-precision arithmetic and programmability under the GNU General Public License, supporting ongoing development for scientific and engineering users since its inception in 2004. Another example is the C47 project, an open-source firmware and software suite for RPN-based scientific calculations, compatible with hardware like the SwissMicros DM42 and emphasizing community-driven enhancements in the 2020s.[56]
In libraries and APIs, RPN support facilitates expression parsing and evaluation across languages. For JavaScript, the calculator-lib package offers functions to process RPN postfix expressions, converting and evaluating them using stack simulation for web-based mathematical tools and interactive applications.[57] Similarly, npm modules tagged with "rpn" enable tree-based analysis and execution of postfix notations, integrating seamlessly into Node.js environments for dynamic computations.[58] These implementations leverage RPN's unambiguous parsing to build robust evaluators, often referencing stack evaluation techniques for efficiency in runtime processing.