<HTML><HEAD>
<!--
--------------
RPN Calculator
--------------
-->
<SCRIPT LANGUAGE="JavaScript"><!-- hide from old browsers
/*
THE JAVASCRIPT COOKBOOK by Erica Sadun, webrx@mindspring.com
Copyright (c)1998 by Charles River Media. All Rights Reserved.
This applet can only be re-used or modifed by license holders of the
JavaScript Cookbook CD-ROM. Credit must be given in the source
code and this copyright notice must be maintained. If you do
not hold a license to the JavaScript Cookbook, you may NOT
duplicate or modify this code for your own use.
Use at your own risk. No warranty is given or implied of the suitability
of this applet for any specific application. Neither Erica Sadun nor
Charles River Media will be held responsible for any unwanted effects
due to the use of this applet or any derivative.
*/
// Create an Array
function createArray(n)
{
this.length = n;
for (var i = 0; i < n; i++) {this[i] = 0}
return this
}
// Initialize Global Variables
stack = createArray(20) // 20 should be big enough
sktop = 0 // Top of the Stack
entry = "0" // Current Entry
restart = true // Number: overwrite (restart) or add (!restart)
// Show the Stack
function showstack(aform)
{
var answer=""
for (var i = 0; i < sktop; i++) answer = stack[i] + ": " + answer
aform.stack.value = answer
}
// Handle a Number Tap
function tap(aform, c)
{
if (restart) // Either new start or stack just pushed
{
aform.answer.value = c
restart = false
}
else if (c == '.') // Add decimal only if unique
{
if (aform.answer.value.indexOf(".") < 0)
aform.answer.value += "."
} else if (aform.answer.value == '0') // Zero gets overwritten
{
aform.answer.value = c
}
else aform.answer.value += c // Add digit
}
// Clear the Current Entry
function clear(aform)
{
aform.answer.value = '0'
restart = true
}
// Handle a Math Request
function req(aform, afunction)
{
if (sktop == 0) // push new value and function
{
// allow unary operations, default to (0 op Number)
entry = eval("0" + afunction + aform.answer.value)
// update the answer and prepare for new number or "enter"
aform.answer.value = entry
restart = true
showstack(aform)
}
else // pop and evaluate
{
var v = stack[sktop-1] // pop stack
sktop--
// derive new answer
var answer = eval(v + afunction + aform.answer.value)
// display it
aform.answer.value = "" + answer
// reset for a new number and show stack
entry =""
restart = true
showstack(aform)
}
}
// Press the All Clear button
function ac(aform)
{
// all clear
aform.answer.value = "0" // reset answer line
restart = true // prepare for a new number
entry = ""
sktop = 0 // reset stack
showstack(aform) // show empty stack
}
// Push the Stack
function push(aform)
{
stack[sktop] = ""+aform.answer.value // push onto stack
sktop++ // increase top of stack
restart = true // prepare for new number
entry = ""
aform.answer.value = "0" // reset input line
showstack(aform) // show stack
}
<!-- done hiding --></SCRIPT></HEAD>
<BODY bgcolor="ffffff" link="0000ff" vlink="770077">
<FONT COLOR="007777"><H1><IMG SRC="../GRAFX/UTENS.JPG" WIDTH=80 HEIGHT=50
ALIGN = CENTER>RPN Calculator</H1></FONT>
<BLOCKQUOTE>
<FONT COLOR="770000">
Try out this reverse polish notation calculator. It works like
some popular scientific calculators. Instead of tapping 5 + 3,
you tap "5", "Enter", "3", "+". Try these:<ul></FONT>
<li> <b>Approximate PI</b>: tap "2", tap "2", tap "Enter", tap "7" and tap "/"
<br><tt><FONT SIZE=2>[Postfix: 22 7 /]</FONT></tt>
<li> <b>Calculate (5+3)/(4-2)</b>: tap "5", tap "Enter", tap "3", tap "+",
tap "Enter", tap "4", tap "Enter", tap "2", tap "-", tap "/".
<br><tt><FONT SIZE=2>[Postfix: 5 3 + 4 2 - /]</FONT></tt>
</ul>
</BLOCKQUOTE>
<BR><BR>
<CENTER><FORM><TABLE BORDER=1>
<TR>
<TD align=center colspan=4><input type="text" name="stack" value="0"
size=23>: STACK</TD>
</TR>
<TR>
<TD align=center colspan=4><input type="text" name="answer" value="0" size=30></TD>
</TR>
<TR>
<TD align=center ><input type="button" value=" 7 " onClick="tap(this.form,'7')"></TD>
<TD align=center ><input type="button" value=" 8 " onClick="tap(this.form,'8')"></TD>
<TD align=center ><input type="button" value=" 9 " onClick="tap(this.form,'9')"></TD>
<TD align=center ><input type="button" value=" / " onClick="req(this.form,' / ')"></TD>
</TR>
<TR>
<TD align=center ><input type="button" value=" 4 " onClick="tap(this.form,'4')"></TD>
<TD align=center ><input type="button" value=" 5 " onClick="tap(this.form,'5')"></TD>
<TD align=center ><input type="button" value=" 6 " onClick="tap(this.form,'6')"></TD>
<TD align=center ><input type="button" value=" * " onClick="req(this.form,' * ')"></TD>
</TR>
<TR>
<TD align=center ><input type="button" value=" 1 " onClick="tap(this.form,'1')"></TD>
<TD align=center ><input type="button" value=" 2 " onClick="tap(this.form,'2')"></TD>
<TD align=center ><input type="button" value=" 3 " onClick="tap(this.form,'3')"></TD>
<TD align=center ><input type="button" value=" - " onClick="req(this.form,' - ')"></TD>
</TR>
<TR>
<TD align=center ><input type="button" value=" C " onClick="clear(this.form)"></TD>
<TD align=center ><input type="button" value=" 0 " onClick="tap(this.form,'0')"></TD>
<TD align=center ><input type="button" value=" . " onClick="tap(this.form,'.')"></TD>
<TD align=center ><input type="button" value=" + " onClick="req(this.form, ' + ')"></TD>
</TR>
<TR>
<TD align=center colspan=3 align=right>
<input type="button" value=" Enter "
onClick="push(this.form)"></TD>
<TD align=center ><input type="button" value=" AC " onClick="ac(this.form)"></TD>
</TR>
</TABLE></FORM></CENTER>
<BR><BR>
<FONT COLOR="007777"><H2>Discussion</H2></FONT>
<FONT SIZE=4>
Unlike the previous calculator example, this RPN calculator
stores arguments in a stack. Operators are entered in postfix order
using reverse polish notation. Each operation pops the stack by
one. The results are shown in the answer line and must be manually
pushed back onto the stack with the "Enter" key. A simple array
called <FONT COLOR="770000">stack</FONT> holds the stack data.
The variable <FONT COLOR="770000">sktop</FONT> points to the
top of the stack. The function below demonstrates a stack push.
After each push, the answer line is reset to zero and the stack
line is updated.
</FONT>
<FONT COLOR="770000"><PRE>
function push(aform)
{
// push onto stack
stack[sktop] = ""+aform.answer.value
// increase the top of the stack
sktop++
// reset the answer to zero
aform.answer.value = "0"
// show the new stack
showstack(aform)
// reset for entering a new number
restart = true
entry = ""
}
</PRE></FONT>
<h5>Copyright ©1996 by Charles River Media, All Rights Reserved</h5>
</BODY>
</HTML>